pchestna

L3D Cube Atom 4 Electrons

Oct 4th, 2015
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.05 KB | None | 0 0
  1. #include <FastLED.h>
  2. #include <Math.h>
  3.  
  4. // Derivative work to: http://pastebin.com/h95EgTkT
  5. // Thanks again to Mark Kriegsman and FastLED
  6. // Work in progress
  7.  
  8. const uint8_t kCubeSize = 8;
  9. const uint8_t kFracs = 16;
  10.  
  11. #define DATA_PIN 2
  12. #define NUM_LEDS kCubeSize * kCubeSize * kCubeSize
  13. #define MAX_POS (kCubeSize-1)*kFracs
  14. #define CENTER MAX_POS/2
  15. #define FILLED_NUCLEUS true
  16. #define E_MIN_RAD 25
  17. #define E_MAX_RAD 54
  18. #define N_MAX_RAD 18
  19. #define N_MIN_POS 32
  20. #define N_MAX_POS 80
  21. #define F88_PI 804
  22. //#define F88_PI 3
  23. #define MIN_THETA 0
  24. #define MAX_THETA 2 * F88_PI
  25. #define MIN_PHI 0
  26. #define MAX_PHI F88_PI
  27. //#define THETA_RES 65535
  28. //#define PHI_RES 65535
  29. #define THETA_RES 60
  30. #define PHI_RES 30
  31. #define LED_TYPE    WS2811
  32. #define COLOR_ORDER GRB
  33. #define MASTER_BRIGHTNESS   255
  34. #define FADE 240
  35. #define NUM_PIXELS 0
  36. #define NUM_ELECTRONS 4
  37. CRGB leds[NUM_LEDS];
  38.  
  39. typedef struct {
  40.   int     F16posX = 0; // x position of the pixel
  41.   int     F16posY = 0; // y position of the pixel
  42.   int     F16posZ = 0; // z position of the pixel
  43.   uint8_t hue = 0;
  44.   uint8_t xPosMod = 1;
  45.   uint8_t yPosMod = 1;
  46.   uint8_t zPosMod = 1;
  47.   uint8_t posMin = N_MIN_POS;
  48.   uint8_t posMax = N_MAX_POS;
  49. } pixel;
  50. pixel pixels[NUM_PIXELS];
  51.  
  52. typedef struct {
  53.   int     F16posX = 0; // x position of the pixel
  54.   int     F16posY = 0; // y position of the pixel
  55.   int     F16posZ = 0; // z position of the pixel
  56.   uint16_t radius = E_MAX_RAD;
  57.   int theta = 0;
  58.   int phi = 0;
  59.   uint8_t thetaOrig = 0;
  60.   int radiusMod = 1;
  61.   bool thetaMod = false;
  62.   bool phiMod = true;
  63.   uint8_t hue = 0;
  64. } electron;
  65. electron electrons[NUM_ELECTRONS];
  66.  
  67. //void initPixelsNucleus()
  68. //{
  69. //  // NUM_PIXELS should be 2 to use only these two values
  70. //  pixels[0].hue = beatsin8(19,HUE_RED,HUE_YELLOW);
  71. //  pixels[0].xPosMod = 143;
  72. //  pixels[0].yPosMod = 91;
  73. //  pixels[0].zPosMod = 74;
  74. //
  75. //  pixels[1].hue = beatsin8(3,HUE_AQUA,HUE_PURPLE);
  76. //  pixels[1].xPosMod = 121;
  77. //  pixels[1].yPosMod = 77;
  78. //  pixels[1].zPosMod = 95;
  79. //}
  80.  
  81. void initNucleusPixelsRandom()
  82. {
  83.   for (int i=0; i<NUM_PIXELS; i++)
  84.   {
  85.     pixels[i].hue = random8();
  86.     pixels[i].xPosMod = random8();
  87.     pixels[i].yPosMod = random8();
  88.     pixels[i].zPosMod = random8();
  89.   }
  90. }
  91.  
  92. void initElectronsRandom()
  93. {
  94.   int thetaOffset = 0;
  95.   for (int i=0; i<NUM_ELECTRONS; i++)
  96.   {
  97.     electrons[i].hue = i*256/NUM_ELECTRONS;
  98.     electrons[i].radiusMod = 1;
  99.     electrons[i].phiMod = (i % 2) ? true : false;
  100.     electrons[i].phi = i*PHI_RES/NUM_ELECTRONS;
  101.     electrons[i].thetaOrig = (i*THETA_RES/NUM_ELECTRONS) + thetaOffset;
  102.   }
  103. }
  104.  
  105. void printElectronPos()
  106. {
  107.   for (int i=0; i<NUM_ELECTRONS; i++)
  108.   {
  109.     Serial.print("Electron (");
  110.     Serial.print(i);
  111.     Serial.print(") [");
  112.     Serial.print(electrons[i].F16posX);
  113.     Serial.print(", ");
  114.     Serial.print(electrons[i].F16posY);
  115.     Serial.print(", ");
  116.     Serial.print(electrons[i].F16posZ);
  117.     Serial.print("] Theta ");
  118.     Serial.print(electrons[i].theta);
  119.     Serial.print(", Phi ");
  120.     Serial.print(electrons[i].phi);
  121.     Serial.print(", Radius ");
  122.     Serial.println(electrons[i].radius);
  123.   }
  124. }
  125.  
  126. //void moveElectrons()
  127. //{
  128. //  for (int i=0; i<NUM_ELECTRONS; i++)
  129. //  {
  130. //    electrons[i].phi = beatsin16(20, 0, 65535);
  131. //    electrons[i].hue++;
  132. //
  133. //    if (electrons[i].phi == 65535)
  134. //      electrons[i].theta = electrons[i].thetaOrig + (THETA_RES/2);
  135. //    else if (electrons[i].phi == 0)
  136. //      electrons[i].theta = electrons[i].thetaOrig;
  137. //
  138. //    electrons[i].F16posX = CENTER + ((electrons[i].radius
  139. //      * cos16(electrons[i].theta)
  140. //      * sin16(electrons[i].phi))/(32767*32767));
  141. //
  142. //    electrons[i].F16posY = CENTER + ((electrons[i].radius
  143. //      * sin16(electrons[i].theta)
  144. //      * sin16(electrons[i].phi))/(32767*32767));
  145. //      
  146. //    electrons[i].F16posZ = CENTER + ((electrons[i].radius
  147. //      * cos16(electrons[i].phi))/32767);
  148. //  }
  149. //
  150. ////  printElectronPos();
  151. //}
  152.  
  153. void moveElectrons()
  154. {
  155.   for (int i=0; i<NUM_ELECTRONS; i++)
  156.   {
  157.     if (electrons[i].phi == PHI_RES)
  158.       electrons[i].phiMod = !electrons[i].phiMod;
  159.  
  160.     electrons[i].phi += (electrons[i].phiMod) ? 1 : -1;
  161.     electrons[i].theta = (electrons[i].phiMod) ? electrons[i].thetaOrig : electrons[i].thetaOrig + (THETA_RES/2);
  162.     electrons[i].hue++;
  163.  
  164.     electrons[i].F16posX = CENTER + (electrons[i].radius * cos((float) PI * electrons[i].theta / THETA_RES)
  165.             * sin((float) PI * electrons[i].phi / PHI_RES));
  166.  
  167.     electrons[i].F16posY = CENTER + (electrons[i].radius * sin((float) PI * electrons[i].theta / THETA_RES)
  168.             * sin((float) PI * electrons[i].phi / PHI_RES));
  169.      
  170.     electrons[i].F16posZ = CENTER + (electrons[i].radius * cos((float) PI * electrons[i].phi / PHI_RES));
  171.  
  172.   }
  173. }
  174.  
  175. void moveNucleusPixels()
  176. {
  177.   for (int i=0; i<NUM_PIXELS; i++)
  178.   {
  179.     pixels[i].F16posX = beatsin16(pixels[i].xPosMod, pixels[i].posMin, pixels[i].posMax);
  180.     pixels[i].F16posY = beatsin16(pixels[i].yPosMod, pixels[i].posMin, pixels[i].posMax);
  181.     pixels[i].F16posZ = beatsin16(pixels[i].zPosMod, pixels[i].posMin, pixels[i].posMax);
  182.     pixels[i].hue++;
  183.   }
  184. }
  185.  
  186. //void fillNucleus()
  187. //{
  188. //  int res = 20;
  189. //  if (! FILLED_NUCLEUS) return;
  190. //  for (int theta=0; theta<res; theta+=2)
  191. //    for (int phi=0; phi<res; phi+=2)
  192. //    {
  193. //      int x, y, z;
  194. //        x = CENTER + (N_MAX_RAD * cos((float) 2 * PI * theta / res)
  195. //              * sin((float) PI * phi / res));
  196. //    
  197. //        y = CENTER + (N_MAX_RAD * sin((float) 2* PI * theta / res)
  198. //              * sin((float) PI * phi / res));
  199. //          
  200. //        z = CENTER + (N_MAX_RAD * cos((float) PI * phi / res));
  201. //        
  202. //        paintPixels(x, y, z, nucleusHue);
  203. //    }
  204. //}
  205.  
  206. void paintPixels(int nx, int ny, int nz, uint8_t hue)
  207. {
  208.     uint8_t x = nx / kFracs; // convert from pos to raw pixel number
  209.     uint8_t y = ny / kFracs; // convert from pos to raw pixel number
  210.     uint8_t z = nz / kFracs; // convert from pos to raw pixel number
  211.     uint8_t fracX = nx & 0x0F; // extract the 'factional' part of the position
  212.     uint8_t fracY = ny & 0x0F; // extract the 'factional' part of the position
  213.     uint8_t fracZ = nz & 0x0F; // extract the 'factional' part of the position
  214.  
  215.     uint8_t px = 255 - (fracX * kFracs);
  216.     uint8_t py = 255 - (fracY * kFracs);
  217.     uint8_t pz = 255 - (fracZ * kFracs);
  218.    
  219.     leds[XYZ(x,y,z)] = CHSV( hue, 255, scale8(px, scale8(py, pz)));
  220.     leds[XYZ(x,y+1,z)] = CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  221.     leds[XYZ(x,y,z+1)] = CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  222.     leds[XYZ(x,y+1,z+1)] = CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  223.     leds[XYZ(x+1,y,z)] = CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  224.     leds[XYZ(x+1,y+1,z)] = CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  225.     leds[XYZ(x+1,y,z+1)] = CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  226.     leds[XYZ(x+1,y+1,z+1)] = CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  227. }
  228.  
  229. void fillNucleus()
  230. {
  231.      paintNucleus(3, 3, 3);
  232.      paintNucleus(3, 4, 3);
  233.      paintNucleus(3, 3, 4);
  234.      paintNucleus(3, 4, 4);
  235.      paintNucleus(4, 3, 3);
  236.      paintNucleus(4, 4, 3);
  237.      paintNucleus(4, 3, 4);
  238.      paintNucleus(4, 4, 4);
  239. }
  240.  
  241. int nb = 32;
  242. int nh = 0;
  243. void paintNucleus(int x, int y, int z)
  244. {
  245.     nb = beatsin8(15, 32, 64);
  246.     nh = beatsin8(7, 0, 255);
  247.     leds[XYZ(x,y,z)] += CHSV( nh, 255, nb);
  248. }
  249.  
  250. void setup() {
  251.   Serial.begin(57600);
  252.   delay(3000); // setup guard
  253.   FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  254.   FastLED.setBrightness(MASTER_BRIGHTNESS);
  255.   initElectronsRandom();
  256.   initNucleusPixelsRandom();
  257. }
  258.  
  259. uint16_t XYZ( uint8_t x, uint8_t y, uint8_t z)
  260. {
  261.   uint16_t i;
  262.  
  263.   i = kCubeSize * ((y * kCubeSize) + x) + z;
  264.  
  265.   if ((i >= 0) && (i <= 512))
  266.     return i;
  267.   else
  268.     return 0;
  269. }
  270.  
  271. // Draw a pixel on a matrix using fractions of light. Positions are measured in
  272. // sixteenths of a pixel.  Fractional positions are
  273. // rendered using 'anti-aliasing' of pixel brightness.
  274. void drawPixels()
  275. {
  276.   for (int i = 0; i < NUM_PIXELS; i++)
  277.   {
  278.     int hue = pixels[i].hue;
  279.    
  280.     uint8_t x = pixels[i].F16posX / kFracs; // convert from pos to raw pixel number
  281.     uint8_t y = pixels[i].F16posY / kFracs; // convert from pos to raw pixel number
  282.     uint8_t z = pixels[i].F16posZ / kFracs; // convert from pos to raw pixel number
  283.     uint8_t fracX = pixels[i].F16posX & 0x0F; // extract the 'factional' part of the position
  284.     uint8_t fracY = pixels[i].F16posY & 0x0F; // extract the 'factional' part of the position
  285.     uint8_t fracZ = pixels[i].F16posZ & 0x0F; // extract the 'factional' part of the position
  286.  
  287.     uint8_t px = 255 - (fracX * kFracs);
  288.     uint8_t py = 255 - (fracY * kFracs);
  289.     uint8_t pz = 255 - (fracZ * kFracs);
  290.    
  291.     leds[XYZ(x,y,z)] += CHSV( hue, 255, scale8(px, scale8(py, pz)));
  292.     leds[XYZ(x,y+1,z)] += CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  293.     leds[XYZ(x,y,z+1)] += CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  294.     leds[XYZ(x,y+1,z+1)] += CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  295.     leds[XYZ(x+1,y,z)] += CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  296.     leds[XYZ(x+1,y+1,z)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  297.     leds[XYZ(x+1,y,z+1)] += CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  298.     leds[XYZ(x+1,y+1,z+1)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  299.   }
  300. }
  301.  
  302. void drawElectrons()
  303. {
  304.   for (int i = 0; i < NUM_ELECTRONS; i++)
  305.   {
  306.     int hue = electrons[i].hue;
  307.    
  308.     uint8_t x = electrons[i].F16posX / kFracs; // convert from pos to raw pixel number
  309.     uint8_t y = electrons[i].F16posY / kFracs; // convert from pos to raw pixel number
  310.     uint8_t z = electrons[i].F16posZ / kFracs; // convert from pos to raw pixel number
  311.     uint8_t fracX = electrons[i].F16posX & 0x0F; // extract the 'factional' part of the position
  312.     uint8_t fracY = electrons[i].F16posY & 0x0F; // extract the 'factional' part of the position
  313.     uint8_t fracZ = electrons[i].F16posZ & 0x0F; // extract the 'factional' part of the position
  314.  
  315.     uint8_t px = 255 - (fracX * kFracs);
  316.     uint8_t py = 255 - (fracY * kFracs);
  317.     uint8_t pz = 255 - (fracZ * kFracs);
  318.    
  319.     leds[XYZ(x,y,z)] += CHSV( hue, 255, scale8(px, scale8(py, pz)));
  320.     leds[XYZ(x,y+1,z)] += CHSV( hue, 255, scale8(px, scale8((255-py), pz)));
  321.     leds[XYZ(x,y,z+1)] += CHSV( hue, 255, scale8(px, scale8(py, (255-pz))));
  322.     leds[XYZ(x,y+1,z+1)] += CHSV( hue, 255, scale8(px, scale8((255-py), (255-pz))));
  323.     leds[XYZ(x+1,y,z)] += CHSV( hue, 255, scale8((255-px), scale8(py, pz)));
  324.     leds[XYZ(x+1,y+1,z)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), pz)));
  325.     leds[XYZ(x+1,y,z+1)] += CHSV( hue, 255, scale8((255-px), scale8(py, (255-pz))));
  326.     leds[XYZ(x+1,y+1,z+1)] += CHSV( hue, 255, scale8((255-px), scale8((255-py), (255-pz))));
  327.   }
  328. }
  329.  
  330. void loop()
  331. {
  332.   // Dim everything
  333.   nscale8(leds, NUM_LEDS, FADE);
  334.  
  335.   moveNucleusPixels();
  336.   moveElectrons();
  337.   drawPixels();
  338.   drawElectrons();
  339.   fillNucleus();
  340.    
  341.   FastLED.show();
  342. }
Advertisement
Add Comment
Please, Sign In to add comment