ripples

pretty simple water ripple simulation

// made by alex
// iamalexbaker@gmail.com
// dailygenerative.art.blog

int cols;
int rows;
float[][][] o;
float[][][] n;
float damping = 0.999;
float[] intensity = {1,5,1};
boolean invertAxes = false; // don't use this if width != height
boolean invertColours = false;
boolean randomise = false;

int nc = 2;
color[] col = new color[2];
color bgc;
float[] params = new float[6];

void setup(){
  size(800,800);
  cols = width;
  rows = height;
  o = new float[cols][rows][3];
  n = new float[cols][rows][3];
  intensity[2] = random(intensity[0], intensity[1]);
  colorMode(HSB, TWO_PI, 1, 1);
  for(int i = 0; i < nc; i++){
    col[i] = color(random(TWO_PI), random(0.5)+0.5, random(0.5)+0.5);
  }
  bgc = color(0,0,0.8);
  colorMode(RGB, 255, 255, 255);
  params[0] = random(3)+0.5;
  params[1] = random(2)+0.5;
  params[2] = random(3);
  params[3] = random(2)+0.5;
  params[4] = random(3);
  params[5] = random(2) + 0.5;
}

void impulse(boolean invert, float a, float b, float c, float d, float e, float f){
  // random curve
  for(float x = 0; x < width; x++){
    float xx = x/width;
    float y = ((pow((xx),a)*b + tan(xx*TWO_PI*c)*d  + sin(xx*TWO_PI*e)*f)) * height;
    if(y > height || y < 0) continue;
    color newColour = lerpColor(col[0], col[1], xx);
    float rr = newColour >> 16 & 0xFF;
    float gg = newColour >> 8 & 0xFF;
    float bb = newColour & 0xFF;
    if(!invert){
      o[int(x)][int(y)][0] = rr*intensity[2];
      o[int(x)][int(y)][1] = gg*intensity[2];
      o[int(x)][int(y)][2] = bb*intensity[2];
    }
    else{
      o[int(y)][int(x)][0] = rr*intensity[2];
      o[int(y)][int(x)][1] = gg*intensity[2];
      o[int(y)][int(x)][2] = bb*intensity[2];
    }
  }
}

void mouseDragged(){
  if(mouseX<0||mouseX>width||mouseY<0||mouseY>height) return;
  o[mouseX][mouseY][0] = random(500);
  o[mouseX][mouseY][1] = random(500);
  o[mouseX][mouseY][2] = random(500);
}

void draw(){
  //println(frameRate);
  background(230);
  loadPixels();
  for(int i = 1; i < cols - 1; i++){
    for(int j = 1; j < rows - 1; j++){
      for(int k = 0; k < 3; k++){
        n[i][j][k] = (o[i-1][j][k] + o[i+1][j][k] + o[i][j-1][k] + o[i][j+1][k]) / 2 - n[i][j][k];
        n[i][j][k] = n[i][j][k] * damping;
      }
      int index = i + j * cols;
      if(invertColours){
        pixels[index] = color(255-n[i][j][0], 255-n[i][j][1], 255-n[i][j][2]);
      } else {
        pixels[index] = color(n[i][j][0], n[i][j][1], n[i][j][2]);
      }
    }
  }
  updatePixels();
  float[][][] temp = o;
  o = n;
  n = temp;
}

void keyPressed()
{
  if (keyCode==32) { // space
    saveFrame("ripple"+hour()+"-"+minute()+"-"+second()+".png");
  }
  if (keyCode==10) { // enter
    setup();
  }
  if(keyCode==90) { // Z
    if(randomise){
      impulse(invertAxes, random(3)+0.5, random(2)+0.5, random(3), random(2)+0.5, random(3), random(2)+0.5);
    } else {
      impulse(invertAxes, params[0], params[1], params[2], params[3], params[4], params[5]);
    }
  }
}

Leave a comment