#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# Alternatives to for loops within draw()?

edited December 2014 in p5.js

Hello again,

I'm trying to write a code that will cycle through all possible color combinations of every pixel for a certain sized canvas. Basically, take the color values in `pixels[]` and increase a value until it gets to 255, then start it over at 0 and increase the next value by 1 until it gets to 255, at which point it will reset and increase the next value by one, etc.

I found a way that I think would do it with a `for` loop, but because of the fact that the loop occurs once every frame, it does this to all pixels at once instead of going pixel by pixel. The loop I've written looks like this:

``````loadPixels();
for (p = 0; p < pixels.length; p++) {

//to avoid alpha values:
if (p % 4 == 3) {
continue;
}

pixels[p] += 1;

if (pixels[p] == 255) {
pixels[p+1] += 1;
pixels[p] = 0;
}
}
updatePixels();
``````

(I'm pretty sure my logic on how I built this is flawed, I still don't have a perfect grasp on javascript)

My thought for that loop was that would function like this:

• Skip alpha values
• For every frame, add 1 to the current value of `pixels[]`
• If the current value of `pixels[]` becomes 255, reset it to zero and add 1 to the next value of `pixels[]`
• Do this continually through the rest of the array.

Instead, the whole canvas just slowly goes from black to white and then repeats. Am I correct in my assumption that this is because the loop is executed once per frame?

I've written super rudimentary code that does a portion of what I need, but the problem with it is that I'd have to write three `if` statements for every pixel of the canvas (which is pretty much impossible). Could somebody tell me how to streamline this? I've been banging my head against the wall on it for a while now.

``````loadPixels();

pixels += 1;

if (pixels == 255) {
pixels += 1;
pixels = 0;
}
if (pixels == 255) {
pixels += 1;
pixels = 0;
}
if (pixels == 255) {
pixels += 1;
pixels = 0;
}
//End first pixel, start second:
if (pixels == 255) {
pixels += 1;
pixels = 0;
}
if (pixels == 255) {
pixels += 1;
pixels = 0;
}
if (pixels == 255) {
pixels += 1);
pixels = 0;
}
//End of second pixel
//etc.
updatePixels();
``````

Tagged:

• Not so sure if I understood correctly what you want there!
Either way, made a "class" called ColorIncreaser in order to streamline & keep tabs of some needed values:
These are the 3 ColorIncreaser's instance variables:

1. p5.Image as img,
2. Its current pixels[]'s index as idx,
3. And optional value increasing step as sp.

Create an instance of it via: `new ColorIncreaser()`. All of its 3 parameters are optional.
After that, you can increase value inside current pixels[]'s index via inc() method or decrease it via dec().
It goes to either next or previous index when trying to inc() w/ `px[idx] == 255` or dec() w/ `px[idx] == 0`.
Besides reseting current value to `0` or `255` respectively 1st! :D

Hope I've hit bull's eye this time. Check it out: (*)

``````/**
* ColorIncreaser Class (v1.11)
* by GoToLoop (2014/Dec/08)
*
* forum.processing.org/two/discussion/8537/
* alternatives-to-for-loops-within-draw
*/

const STEP = 4, BG = 0150;
var colInc, forward = true;

function setup() {
createCanvas(100, 100);
frameRate(100).background(BG);
colInc = new ColorIncreaser(null, STEP);
}

function draw() {
forward? colInc.inc() : colInc.dec();

/*print(colInc.idx + '\t' + (colInc.img
? colInc.img.pixels[colInc.idx]
: pixels[colInc.idx]));*/
}

function mouseClicked() {
print('Forward? ' + (forward = !forward));
}

function ColorIncreaser(img, sp, idx) {
img instanceof p5.Image || (img = null);

this.sp = abs(+sp || 1);

const len = img? img.pixels.length : pixels.length;
this.idx  = min(abs(+idx || 0), len-2);
}

ColorIncreaser.prototype.inc = function() {
const px = this.img? this.img.pixels : pixels;

if (px[this.idx] == 0xff)
px[this.idx] = 0, this._next(px.length);

px[this.idx] += this.sp;
this.img? this.img.updatePixels() : updatePixels();
}

ColorIncreaser.prototype._next = function(len) {
(++this.idx & 3) == 3 && ++this.idx;
if (this.idx >= len)  this.idx = 0;
}

ColorIncreaser.prototype.dec = function() {
const px = this.img? this.img.pixels : pixels;

if (!px[this.idx])
px[this.idx] = 0xff, this._prev(px.length);

px[this.idx] -= this.sp;
this.img? this.img.updatePixels() : updatePixels();
}

ColorIncreaser.prototype._prev = function(len) {
(--this.idx & 3) == 3 && --this.idx;
if (this.idx < 0)  this.idx = len-2;
}
``````
• Thanks for taking a look at this, GoToLoop! What you've written is almost it, there's one thing that's different though.

When `px[idx] == 255` it resets `px[idx]` to `0` and increases `idx` by one. Basically meaning that it only focuses on changing the color value of one pixel at a time. I'm trying to get it to continue increasing the initial pixel while increasing the subsequent pixel, which would then go on to increase the pixel after that, etc. What I'm trying to set up is something that basically would function like an odometer:

[ r ] [ g ] [ b ] [ a ] [ r ] [ g ] [ b ] [ a ]

(Here the brackets are just delineating the individual wheels of an odometer, not meaning arrays)

[ 0 ] [ 0 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

(255 because the alpha values start there and should stay there)

As the first red value hits 255:

[ 255 ] [ 0 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] 

The next value, the green value, becomes 1 and the red resets to 0.

[ 0 ] [ 1 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

Then red1 continues to go up to 255 and reset to zero, raising green1 each time it completes a cycle:

[ 255 ] [ 1 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

[ 0 ] [ 2 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

This happens until green1 gets to 255, at which point it advances blue1 by one, and resets itself to 0.

[ 255 ] [ 255 ] [ 0 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

[ 0 ] [ 0 ] [ 1 ] [ 255 ] [ 0 ] [ 0 ] [ 0 ] [ 255 ]

From here, the red1 value has to cycle to 255 to advance green1 255 more times in order for the blue1 to become 2. And then once blue1 hits 255 and returns to 0, red2 (the first red after the alpha value) increases by one.

Is there some way to make this happen? I've written a mathematic formula for how long it would take each slot to advance, but I don't really know how to translate it into code that Javascript can actually use:

``````//Assuming the first index, or red1, goes from 0 to 255 once every second:
color value of any index place = seconds/256^(index place)

or, using the names you set up in ColorIncreaser:
px[idx] = seconds/256^(idx-1)

Since the first value ( px ) hits 255 and resets to 0 once every second,
that means the second value ( px ) increases by 1 every second:

seconds = 1
px = 1/256^0
px = 1/1

and that the third value, green of the first pixel ( px ),
will increase by one every 256 seconds.

seconds = 256
px = 256/256^1
px = 256/256 = 1

Values further down in the array take an increasingly longer
amount of time to advance, *255 for each place.
``````

Does that make it any clearer?

I realize this looks really inefficient or strange, but the idea is that it is something that is supposed to unfold over a very long amount of time

• I believe that if there were a way for me to get the `if` statements I wrote in the original post to work like a formula the solution would be pretty simple:

``````if (pixels[currentValue] == 255) {
pixels[nextValue] += 1;
pixels[currentValue] = 0;
}
``````

I'd still have to adjust to avoid the alpha values, but that would get me 99% there. Is there anything built into either P5.js or Javascript that would allow me to do something like that?

• edited December 2014 Answer ✓

255 * 255 * 255=16581375

``````int[] d;

void setup() {
size(220, 220);
d = new int; // [width*height*3];
for (int i=0; i<d.length; d[i++]=0);
}
void draw() {
int i=0;
boolean go=true;
// int counter=0;
while (go) {
if (d[i]>=255) {
d[i]=0;
i++;
} else {
d[i]+=5;
go=false;
}
//   counter++;
}
// if (counter > 2000) {
//   println("WARN");
//  }
for (int j=0; j<d.length; j+=3) {
//pixels[j/3]=color(d[j], d[j+1], d[j+2]);
fill(d[j], d[j+1], d[j+2]);
rect(10*(j/3),0,10,10);
}
//  for(int t=0;t<d.length;t++){
//    print( d[t] + " ");
//  }
//  println("");
//  updatePixels();
}
``````

Do whatever with this.

• .

• TfGuy44, thanks! I hadn't considered breaking it into an if/else statement. This should work quite well. And thanks again to GoToLoop for taking a serious stab at it. You guys are awesome!