Cyrill
Cyrill

Reputation: 833

How to slow down random color generator in Processing?

Hi everyone – I want to make a grid pattern of rectangles with random filling colors out of an array.I can get it done the way I want – but the random selection is way too speedy. I tried to slow everything down with frameRate(); – but this slows down the whole animation. (For example if I want to add something else). Then I tried to slow it down with if(frameCount%20 == 0) {…} but this does not keep the drawn grid – only lets it appear every XXX frames for one frame – does someone have an idea how I could slow down the lets call it "Color Noise"? – Thank you for any kind of help!

float size = 20;
color cbw = color(0, 0, 0);      //defines BLACK
color cg = color(0, 255, 0);     //defines GREEN
color cb = color(0, 0, 255);     //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = {             //random selects one of above colors
cbw, cg, cb, cw
}; 

void setup() {
  size(1080, 1080);

}

void draw() {
  background(255);

  for (int x = 0; x < width/size; x++) {
    for (int y = 0; y < height/size; y++) {
      color c1 = (colors[int(random(0, 4))]);  //assigns a random color from above to c1-4
      fill(c1);
      noStroke();
      rect(size*x, size*y, size, size);
    }
  }
  }

Upvotes: 0

Views: 786

Answers (1)

George Profenza
George Profenza

Reputation: 51867

You're on the right track with frameCount % 20. (Alternatively you can use millis())

The main issue is the colour selection is tightly coupled with the rectangle drawing. In plain English, currently you can only select random colours and render at the same time, but not select colours and render independently (e.g. at different times)

One option is to use an array to store the colours for every rectangle which you can use twice:

  1. to write values to: pick random colours
  2. to read values from: when rendering the rectangles

Here's a modified version of your sketch that illustrated the idea above:

float size = 20;
color cbw = color(0, 0, 0);      //defines BLACK
color cg = color(0, 255, 0);     //defines GREEN
color cb = color(0, 0, 255);     //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = {             //random selects one of above colors
cbw, cg, cb, cw
}; 
// all colors for each rect
color[][] rectColors;

void setup() {
  size(1080, 1080);
  // allocate invidual rect colours
  rectColors = new color[width/(int)size][height/(int)size];
}

void draw() {
  background(255);
  
  if(frameCount%20 == 0){
    // randomize colours
    int numColors = colors.length;
    for (int x = 0; x < width/size; x++) {
      for (int y = 0; y < height/size; y++) {
        rectColors[x][y] = colors[int(random(0, numColors))];
      }
    }
  }

  for (int x = 0; x < width/size; x++) {
    for (int y = 0; y < height/size; y++) {
      color c1 = rectColors[x][y];  //assigns a random color from above to c1-4
      fill(c1);
      noStroke();
      rect(size*x, size*y, size, size);
    }
  }
 }

Personally, I would do a few extra things to make this easier to read and potentially re-use in other sketches:

  1. change float size = 20; to int size = 20; assuming you want the grid cells to land on whole pixels. This removes the need to cast (e.g. width/(int)size)
  2. cache/store data that is often re-used (such as grid rows and columns)
  3. encapsulate the loops that randomize colours and render rectangles into separate functions. Even something as simple as functions that return no values and take no arguments (e.g. much like void setup() for example)

Here is what that could look like:

int size = 20;
color cbw = color(0, 0, 0);      //defines BLACK
color cg = color(0, 255, 0);     //defines GREEN
color cb = color(0, 0, 255);     //defines BLUE
color cw = color(255, 255, 255); //defines WHITE
color[] colors = {             //random selects one of above colors
cbw, cg, cb, cw
}; 
// all colours for each rect
color[][] rectColors;

// grid dimensions
int cols;
int rows;

void setup() {
  size(1080, 1080);
  // compute grid dimensions
  cols = width / size;
  rows = height / size;
  // allocate invidual rect colours
  rectColors = new color[cols][rows];
  // call randomize colours function
  randomizeColors();
}
// declare randomize colours function
void randomizeColors(){
  // read array length, avoding the previosuly hardcoded value (4)
  int numColors = colors.length;
  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {
      rectColors[x][y] = colors[int(random(0, numColors))];
    }
  }
}

void drawRectangles(){
  for (int x = 0; x < cols; x++) {
    for (int y = 0; y < rows; y++) {
      color c1 = rectColors[x][y];  //read a random color
      fill(c1);
      noStroke();
      rect(size * x, size * y, size, size);
    }
  }
}

void draw() {
  background(255);
  
  if(frameCount % 20 == 0){
    randomizeColors();
  }
  
  drawRectangles();
  
 }

Upvotes: 3

Related Questions