Hey folks, I thought I nailed it yesterday,

Hey folks,

I thought I nailed it yesterday, but my scale function apparently works not with all parameter combinations.
I spend half of the night trying to fix it, but I have no ideas anymore. I stripped the sketch down to the bare minimum. Instead of noise it fills the noise array with values from 0-255. That I map into a rectangle using the RainbowStripColors palette.
The rectangle is defined by 4 values describing 2 2d coordinates. Here is the complete code:

As long as the first coordinate is 0/0 (upper left) everything works as expected. It looks like in this video:

If the first coordinate is a different point the scaling works somethimes, sometimes not. I made a video showing how it looks if I set the 2nd point to 15/15 (down right at my setup) and move the 1st point arround:

The rainbow with stripes (and nothing else) is the content of the noise array. So, the result we see when the moving point is at the upper left edge is basically the picture I would expect to see always - just in different sizes.

It seems to work always fine in x direction and basically exactely the same formula produces a problem in y direction.
I have no theory left, what could cause these behaviour.

I would appreciate it very much if you could have a look into the code and give me a hint, what is going wrong here.

Thank you in advance!

I have spent some time looking at it and I don’t have much…I think its this line though seems perhaps suspect to me…
uint8_t index = noise[i * (kMatrixWidth-1) / (x2-x1)][j * (kMatrixHeight-1) / (y2-y1)];
Just a hunch on my part as the rest seems pretty much the same regardless…

When I am at home I will resolve the formula into smaller parts and watch every single operator in the serial monitor. I mean, I wrote way more complex stuff and it always worked out but these little formula is driving me crazy. It really scratches my ego… :wink:

I completely understand. I have spent hours writing patterns that end up smaller that this… the devil is in the details…

So, let’s say you have (10,10) and (12,12). When I is 10 and J is 10, then from your math - you’re going to have noise[(10 * 15) / (12-10)][(10*15)/(12-10)] - or noise[75][75] - doesn’t sound right :slight_smile:

try uint8_t index = noise[(i-x1) * (kMatrixWidth-1) / (x2-x1)][(j - y1) * (kMatrixHeight-1) / (y2-y1)];

which will then give you noise[(015)/2][(015)/2] or noise[0][0]. Basically, you want to rebase i/j for the lookups into the noise table (since, i’m assuming, what you’re doing is just scaling the entire noise matrix to fit in the box bounded by (x1,y1) & (x2,y2))

Also, this might, in theory, save you about 10-12 cycles per pixel[1] (on avr) over the above (measure to be sure!)

uint8_t dx = x2-x1;
uint8_t dy = y2-y1;

uint8_t noise_x = 0;
for(uint8_t i=x1; i <= x2; i++, noise_x += (kMatrixWidth-1)) {
uint8_t noise_y = 0;
for(uint8_t j=y1; j <= y2; j++, noise_y += (kMatrixWidth-1)) {
uint8_t index = noise[noise_x/dx][noise_y/dy];
uint8_t bri = 255;

  if(colorloop) { index += ihue; }
    
  leds[XY(i,j)] = ColorFromPalette(currentPalette, index, bri);
}

}

Granted, you still have that divide in there which is going to be expensive :confused:

(Also - GCC is still going to do some stupid things like promote things that you know can stay in 8-bit values to 16-bit for math, etc…).

Don’t mind me, I often run through this mental exercise with every bit of code I look at. (Though, again, I usually prefer to time/measure before committing to changes :slight_smile:

That solves the issue. Thank you for correcting the formula and thanks for the optmization hint! Calculating the width and hight of the box just once outside the loop makes totally sense. So I mixed the absolute and the relative counts. I feel ashamed. But I learned something about wrong assumtions: never trust a test which manipulates not all parameters. That led me on the wrong track (“SOMETIMES it works - so the formula has to be right”… yes, with x1=0 and y1=0…) Reminds me somehow of the book “Zen and the art of motorcycle maintenance” :slight_smile: Again, I appreaciate a lot, that you spend your precious time on my problem!

I’ve gotten used to, when the code looks right, but doesn’t do what I expect it to, either doing the math by hand on paper, or tweaking the code to spit out a bunch of debugging values - and then compare what I get to what I expected. Honestly, until I did that, I thought your code looked right!

@Daniel_Garcia that is exactly what I do as well… I hone in on the equation that seems the most complicated and in this case the one that would have the most different outcome based on the test if what was being done. Then output a cycle of the parms and see what happens. Also just by looking at the light behavior and randomness of the lower right hand corner had me thinking there was an overrun in storage …

Now i t would be cool to see the full oscillation in a circle to push the pattern around the corners…

A demo will come… Could you describe precisely, what “push around the corners” means?

The “working” video showed the pattern in the top left corner. The “not working” video showed the pattern in the lower right corner. By pushing around the corners I would meant to do the top left corner, then move the pattern to the top right corner, then the lower right corner and finally the lower left corner, repeat.

Now I get it, I will include that in the demo…