atuline

voronoi.ino

Jun 14th, 2021 (edited)
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.87 KB | None | 0 0
  1. /*  File: Voronoi diagram - animated.
  2.  
  3.     By: Andrew Tuline
  4.  
  5.     Date: June 2021
  6.  
  7.     Slowest implementation in the world of a Voronoi diagram for an Arduino UNO/Nano and the FastLED display library.
  8.  
  9.     Reference:
  10.  
  11.     https://en.wikipedia.org/wiki/Voronoi_diagram
  12.  
  13.     Caveat: There are probably still one or more bugs in this, but it was a fun exercise.
  14.  
  15. */
  16.  
  17.  
  18. #include <FastLED.h>
  19.  
  20. #define matrixWidth 16
  21. #define matrixHeight 16
  22.  
  23. #define matrixSerpentine true
  24.  
  25. #define LED_DT 12
  26.  
  27. #define LED_TYPE WS2812
  28. #define NUM_LEDS matrixWidth*matrixHeight
  29.  
  30. uint8_t max_bright = 128;
  31.  
  32. struct CRGB leds[NUM_LEDS];
  33.  
  34. const uint8_t maxStars = matrixWidth * matrixHeight / 32;
  35.  
  36. typedef struct star {
  37.   float xStart;
  38.   float yStart;
  39.   float x;
  40.   float y;
  41.   uint8_t colr;
  42. } Star;
  43.  
  44.  
  45. Star stars[maxStars];
  46.  
  47.  
  48. void setup() {
  49.   Serial.begin(115200);
  50.   LEDS.addLeds<WS2812, LED_DT, GRB>(leds, NUM_LEDS);
  51.   FastLED.setBrightness(max_bright);
  52.  
  53.   for (int i = 0; i < maxStars; i++) {
  54.     stars[i].xStart = random8(matrixWidth) / 2;
  55.     stars[i].yStart = random8(matrixHeight) / 2;
  56.     stars[i].colr = random8();
  57.   }
  58. } // setup()
  59.  
  60.  
  61. void loop() {
  62.   voronoi();
  63.   Serial.println(LEDS.getFPS());
  64.   FastLED.show();
  65. } // loop()
  66.  
  67.  
  68. void voronoi() {
  69.  
  70.   random16_set_seed(4832);                 // I use this to make repeating random numbers for the phase shift. Think of it as a 0 byte random() array.
  71.  
  72.   for (int i = 0; i < maxStars; i++) {
  73.     stars[i].x = stars[i].xStart + beatsin8(7, 0, matrixWidth, 0, random8()) / 2;
  74.     stars[i].y = stars[i].yStart + beatsin8(8, 0, matrixHeight, 0, random8()) / 2;
  75.   }
  76.  
  77.   for (int x = 0; x < matrixWidth; x++) {
  78.     for (int y = 0; y < matrixHeight; y++) {
  79.       float dist = 99;
  80.       uint8_t indexx = 0, indeyy = 0, scolr = 0;
  81.       for (int star = 0; star < maxStars; star++) {
  82.  
  83.         // Get length to each star.
  84.         float thisDist = sqrt(abs(stars[star].x * stars[star].x - x * x) + abs(stars[star].y * stars[star].y - y * y));
  85.  
  86.         // For the closest star, get current x, y and colour of that star's area.
  87.         if (thisDist < dist) {
  88.           dist = thisDist;
  89.           indexx = x;
  90.           indeyy = y;
  91.           scolr = stars[star].colr;
  92.         } // if
  93.       } // for star
  94.  
  95.       leds[XY(indexx, indeyy)] = CHSV(scolr, 255, 128 / (dist / 4));
  96.  
  97.     } // for y
  98.   } // for x
  99.  
  100.   for (int star = 0; star < maxStars; star++) leds[XY(stars[star].x, stars[star].y)] = CHSV(0, 0, 128);
  101.  
  102. } // voronoi()
  103.  
  104.  
  105. uint16_t XY( uint8_t x, uint8_t y) {            // Returns with the wiring layout.
  106.  
  107.   uint16_t i;
  108.  
  109.   if ( matrixSerpentine == false) {
  110.     i = (y * matrixWidth) + x;
  111.   }
  112.  
  113.   if ( matrixSerpentine == true) {
  114.     if ( y & 0x01) {
  115.       uint8_t reverseX = (matrixWidth - 1) - x;
  116.       i = (y * matrixWidth) + reverseX;
  117.     } else {
  118.       i = (y * matrixWidth) + x;
  119.     }
  120.   }
  121.   return i;
  122.  
  123. } // XY()
Add Comment
Please, Sign In to add comment