CAROL DINH ✦

>> ls ~/work
  • >> 2025
  • >> 2024
  • >> 2023
  • >> 2022
  • >> 2021
>> cd ~/happenings >> cd ~/writing >> cd ~/professional >> cd ~/about


Jitter (2022)

A series of generative art pieces created in Java with Processing. My process was inspired by the color jitter setting of Photoshop brushes, and I sought to script an effect emulating it.

Below is a screen recording of the generative process.


Processing source code

float hueJitter, satJitter, briJitter, jitterMax;
color c;

int[] from = new int[2];
int[] to = new int[2];
int[] curr = new int[2];

boolean vert = true;

float count = 0;
float total = 1;
float brushSize;

int iterations;
int[] boundaries = {int(random(3, 6)), int(random(20, 60)), int(random(80, 100))};

float noiseVal = 0;

boolean started = false;
int current_frame = 0;

void setup(){
  size(1000, 1000);
  background(60);
  colorMode(HSB, 360);
  noStroke();
  c = color(random(360), random(360), random(360));
  jitterMax = sqrt(hue(c - 120) + saturation(c - 120) + brightness(c - 120)) * 3;
  from[0] = int(random(width));
  from[1] = int(random(height));
  if(vert){
    to[0] = from[0];
    to[1] = int(random(height));
  } else {
    to[0] = int(random(width));
    to[1] = from[1];
  }
  vert = !vert;
  float distance = distance(from, to);
  brushSize = width;
  total = int(distance / brushSize * random(5, 20));
  println("(" + from[0] + ", " + from[1] + ") to (" + to[0] + ", " + to[1] + ")");
  started = true;
}

void draw(){
  if(started && iterations < boundaries[2]){
    if(count != total){
      float x = lerp(from[0], to[0], count / total);
      float y = lerp(from[1], to[1], count / total);
      brush(x, y);
      count++;
    } else {
      count = 0;
      c = color((hue(c) + noise(noiseVal) * 360) % 360, (saturation(c) + noise(noiseVal) * 360) % 360, (brightness(c) + noise(noiseVal) * 360) % 360);
      jitterMax = sqrt(hue(c - 120) + saturation(c - 120) + brightness(c - 120)) * 3;
      from[0] = to[0];
      from[1] = to[1];
      if(vert){
        to[0] = from[0];
        to[1] = int(random(height));
      } else {
        to[0] = int(random(width));
        to[1] = from[1];
      }
      vert = !vert;
      float distance = distance(from, to);
      println("(" + from[0] + ", " + from[1] + ") to (" + to[0] + ", " + to[1] + ")");
      if(iterations < boundaries[0]){
       brushSize = random(width / 2, width);
      } else if(iterations < boundaries[1]){
       brushSize = random(width / 10, width / 4);
      } else if(iterations < boundaries[2]){
       brushSize = random(width / 50, width / 20);
      };
      total = int(distance / brushSize * random(5, 20));
      iterations++;
      noiseVal += 0.3;
    }
  }
  else if(started) {
    noLoop();
    int brightness = int(random(2)) * 360;
    fill(0, 0, int(random(2)) * 360, 60);
    rect(0, 0, width, height);
    loadPixels();
    float h, s, b;
    for(int x = 0; x < width; x++){
      for(int y = 0; y < height; y++){
        h = (hue(pixels[x + y * width]) + random(60)) % 360;
        s = min(saturation(pixels[x + y * width]) + random(60), 360);
        b = min(brightness(pixels[x + y * width]) + random(60), 360);
        pixels[x + y * width] = color(h, s, b);
      }
    }
    updatePixels();
    strokeWeight(width / 500);
    stroke(0, 0, brightness);
    noFill();
    
    // Start outside shapes
    int numShapes = int(random(10, 20));
    for(int i = 0; i < numShapes; i++){
      float rectWidth = random(width / 6, width / 2);
      float rectHeight = random(height / 6, height / 2);
      float startX = random(0.1 * width, 0.9 * width - rectWidth);
      float startY = random(0.1 * height, 0.9 * height - rectHeight);
      float cornerRadius = random(width / 400, width / 10);
      rect(startX, startY, rectWidth, rectHeight, cornerRadius);
    }
    int numDots = int(random(width / 20, width / 10));
    for(int i = 0; i < numDots; i++){
      rect(random(0.1 * width, 0.9 * width), random(0.1 * height, 0.9 * height), (width / 200), (width / 200));
    }
    fill(0, 0, brightness);
    numDots = int(random(width / 20, width / 10));
    for(int i = 0; i < numDots; i++){
      rect(random(0.1 * width, 0.9 * width), random(0.1 * height, 0.9 * height), (width / 200), (width / 200));
    }
     save(str(year()) + str(month()) + str(day()) + "_" + str(hour()) + str(minute()) + str(second()) + str(millis()) + ".png");
  }
}

void brush(float x, float y){
  hueJitter = random(-1 * jitterMax, jitterMax);
  satJitter = random(-1 * jitterMax, jitterMax);
  briJitter = random(-1 * jitterMax, jitterMax);
  fill(hue(c) + hueJitter, saturation(c) + satJitter, brightness(c) + briJitter, 36);
  float sideLength = brushSize;
  quad(x, y-sideLength, x+sideLength, y, x, y+sideLength, x-sideLength, y);
}

float distance(int[] from, int[] to){
  return(sqrt(sq(from[0] - to[0]) + sq(from[1] - to[1])));
}