sqr

four sides

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

float midSquare = 3.5;
float gap = 1;
float minLen = 3;
int maxPower = 2; // 1 - will always divide into 2, 2 - divides into 2 or 4, 3 - 2, 4 or 8
float colourRange = 1;
boolean innerSquare = false;
float drawChance = 1.0;
float fillAlpha = 150;
boolean alwaysFinish = false; // doesn't work yet

float midSquareSize;
PVector origin;

int nc = 2;
color[] c = new color[nc];

class edge{
  PVector dir;
  
}

void setup(){
  size(800,800);
  origin = new PVector(width/2, height/2);
  rectMode(CENTER);
  colorMode(HSB, TWO_PI, 1, 1);
  
  for(int i = 0; i < nc; i++){
    c[i] = color(random(TWO_PI), random(1), random(1));
  }
  stroke(0,0,0,200);
  noStroke();
  background(0, 0, 0.8);
  //bggrid(40, 4);
  fill(c[0], fillAlpha);
  midSquareSize = width/midSquare;
  
  if(innerSquare && random(1) < drawChance) rect(origin.x, origin.y, midSquareSize-gap*2, midSquareSize-gap*2);
  subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(origin.x, origin.y - midSquareSize/2), midSquareSize, new PVector(0,-1), true);
  subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(origin.x, origin.y + midSquareSize/2), midSquareSize, new PVector(0,1), true);
  subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(origin.x - midSquareSize/2, origin.y), midSquareSize, new PVector(-1,0), true);
  subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(origin.x + midSquareSize/2, origin.y), midSquareSize, new PVector(1,0), true);
}

void bggrid(int div, float gap){
  
  float n = width/div;
  for(int i = 0; i < div; i++){
    for(int j = 0; j < div; j++){
      fill(PI * ((j+i)%2), 0.2, 0.2);
      rect(i*n + n/2, j*n + n/2, n - gap*2, n - gap*2);
    }
  }
}

void subdivide(int n, PVector mid, float len, PVector dir, boolean corner){
  float x, y;
  float newLen = len/n;
  if(newLen < minLen){
    if(alwaysFinish){
      while (newLen < minLen){
          
          newLen *= 2;
          n /= 2;
          println(newLen+" "+minLen+" "+n);
      } 
      if(n<2) return;
    }
    else return;
  }
  PVector newMid = new PVector(mid.x + (dir.x * newLen * 0.5), mid.y + (dir.y * newLen * 0.5));
  PVector divDir = new PVector(dir.y, dir.x);
  PVector start = new PVector((newMid.x + newLen/2 * divDir.x) - (divDir.x * newLen*(n/2)), (newMid.y + newLen/2 * divDir.y) - (divDir.y * newLen*(n/2)));
  PVector step = new PVector(newLen * divDir.x, newLen * divDir.y);
  for(int i = 0; i < n; i++){
    x = start.x + step.x * i;
    y = start.y + step.y * i;
    fill(lerpColor(c[0], c[1], origin.dist(new PVector(x, y))/(width/colourRange)), fillAlpha);
    if(random(1) < drawChance) rect(x, y, newLen - gap*2, newLen - gap*2);
    subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(x + (dir.x * newLen * 0.5), y + (dir.y * newLen * 0.5)), newLen, dir, false);
  }
  if(corner){
    x = start.x - step.x;
    y = newMid.y + (newMid.y - (start.y - step.y)); // have to invert the corners for one axis because of Processing's backwards y axis
    fill(lerpColor(c[0], c[1], origin.dist(new PVector(x, y))/(width/colourRange)), fillAlpha);
    if(random(1) < drawChance) rect(x, y, newLen - gap*2, newLen - gap*2);
    subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(x + (dir.x * newLen * 0.5), y + (dir.y * newLen * 0.5)), newLen, dir, true);
    subdivide(int(pow(2,int(random(maxPower))+1)), new PVector(x - (divDir.x * newLen * 0.5), y + (divDir.y * newLen * 0.5)), newLen, new PVector(-divDir.x, divDir.y), false);
  }
}

void draw(){}

void keyPressed()
{
  if (keyCode==32) {
    saveFrame("sq-"+hour()+"-"+minute()+"-"+second()+".png");
  }
  if (keyCode==10) {
    setup();
  }
}

Leave a comment