OK, I have XY mapping working, and it looks alright,

OK, I have XY mapping working, and it looks alright, but I feel like I’m doing it wrong. It’s so irregular that I was driving myself crazy trying to get each pixel in its own grid cell. I finally just divided it up into a 10x10 uniform grid, but that puts multiple pixels in the same cell, so I had to use a three dimensional array (10x10x2). Many cells don’t have any pixels, and some just have one, so I mapped the empty slots to a 101th non-visible pixel (similar to the RGB shades XY mapping).

Anyway, here’s the source, feedback welcome, as always: https://github.com/jasoncoon/fibonacci/blob/gh-pages/fibonacci.ino#L656
http://www.youtube.com/watch?v=R6hkl7T7tek

Wow, how did you think to use a three dimensional array? Looks like it’s working pretty well though.
I’m wondering if @Jim_Bumgardner might have any suggestions for mapping?

A completely different approach is this: record the X,Y position of each pixel on an abstract grid, say 0-255 for X and 0-255 for Y. One way to do that would be:

  1. take a photo of the layout.
  2. print it.
  3. write the pixel ID number of each pixel next to each on the photo
  4. overlay some graph paper, and label the axes 0…255 for X and for Y
  5. for each pixel, in ID number order, measure the X and Y coordinate of each pixel, and record them

Now put it all into the computer. It might be something like this:

const uint8_t Xcoord[NUM_LEDS] = { 23, 24, 25, … whatever… };
const uint8_t Ycoord[NUM_LEDS] = { 179, 152, …etc… };

NOW you can do all SORTS of interesting things if you define your animations as a function like this:

pixelcolor = AnimFn( X, Y, time);

And lo and behold it turns out that the Noise functions are perfect for this. You don’t need one pixel per rectangular cell; you just need to know where in the XY world each pixel is located, and what the color should be at any point in space given the coordinates (and time).

Now of course, there are ways to do the X,Y coordinate mapping without graph paper and a pencil, but I’ll leave those as an exercise for the reader with a laptop, a webcam, a working knowledge of Processing, and 6-8 hours to kill. If you’re only going to do it once, it’s probably faster on paper!

Brilliant! Thanks Mark, I can’t wait to try this! I started a similar approach, but backed off when I realized how much space even a 64x64 array would take. I didn’t think about just using an array the size of the actual LED count, for some reason. :slight_smile:

It flips the animating paradigm inside out, and requires some different thinking. Instead of starting with an integer-grid of adjacent square cells, you’re semi-randomly picking and choosing ‘points’ to sample across a much large space of virtual animation.

Some things it’s easy to figure out how to do this way. For example, you could map the X coordinate directly into hue (or a color palette), and poof- you’ve got a horizontal color wash. Offset it by ‘time’, and you get a scrolling wash:

CRGB AnimFn( X, Y, timeInMillis) {
return CHSV( X + (timeInMillis / 100), 255, 255);
}

For other things, it’s harder to figure out how to do it, and you wind up needing additional ‘backing storage’, e.g., you can’t really do something like “Fire2012” without some additional storage.

Penultimately: since the X and Y positions are fixed, these arrays can be “const” and “PROGMEM” – and not even take up any SRAM.

And finally: you can also perform transforms on the X and Y arrays before you call your AnimFn. For example, if you had fast sin/cos, you could rotate all the LEDs around a central point a certain number of ‘degrees’, which could vary – giving a rotating pattern “for free”. There’s a lot you can do here if you’re willing to dig in to the complications.

Thanks Mark, it’s working splendidly! It allows for very smooth animation. I have your suggestions of noise, color, and palette washes working so far. I definitely want to try out rotation, then I’ll get a couple of new ideas working and share some video, hopefully soon.

That’s great! DId you use paper and pencil, or a computer technique?

And full credit to @Daniel_Garcia who first showed me this implementation and how well it works with Noise.

I already had the layout in an image file, so I just used http://getpaint.net to crop and resize it down to 256x256. Then I just typed up the coordinates from the status bar for each point, in index order. Thanks to you both!

Ah, nice trick Jason.

Great discussion, very inspiring!

Thanks, Stefan, we’ve missed you around here lately. Welcome back! :slight_smile:

@Jason_Coon : I had some time inspecting your Fibonacci code… in your xyMap-array are some z-tuples with values>100. How is that? It looks wrong, as you use them to add color to LEDs. But NUM_VIRTUAL_LEDS is just 101 (100 real LEDs plus one virtual to let “100” don’t go wrong). I’m sure, 133 162 or 193 will write to wrong memory regions… or did I miss something?

In spiralPath1Arms you have 91 twice, while the first occurrence should be 81. Here I’m really sure. :slight_smile:

Those seem to be a typos, probably from a find/replace gone bad. Those should likely all be 100 (meaning no LED that slot). The setPixelXY function will ignore anything that’s not under NUM_LEDS anyway.

I’ll probably be revisiting the code some time this week, I’ll check out spiralPath1Arms then. Thanks!