読者です 読者をやめる 読者になる 読者になる

Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

崩壊したシェルピンスキーのカーペット

/**
* Disrupted Sierpinski Carpet
*
* @author aa_debdeb
* @date 2015/10/09
*/


int MAX_DEPTH = 5;
int MAX_SIZE = 500;

float MAX_XY_NOISE_RATIO = 0.3;
float MAX_SIZE_NOISE_RATIO = 0.3;

Square root;

void setup(){
  size(500, 500);
  smooth();
  noStroke();
  frameRate(24);
  
  root = new Square();
}

void draw(){
  background(255);
  root.draw();
  root.update();
}

class Square{
  PVector topLeft;
  float size;
  int depth;
  ArrayList<Square> children;
  float noiseX;
  float noiseY;
  float noiseSize;
  
  Square(){
    this.topLeft = new PVector(0, 0);
    this.size = MAX_SIZE;
    this.depth = 0;
    this.noiseX = random(10);
    this.noiseY = random(10);
    this.noiseSize = random(10);
    this.children = new ArrayList<Square>();
    if(this.depth != MAX_DEPTH){
      makeChildren();
    }
  }
  
  Square(float x, float y, float size, int depth){
    this.topLeft = new PVector(x, y);
    this.size = size;
    this.depth = depth;
    this.noiseX = random(10);
    this.noiseY = random(10);
    this.noiseSize = random(10);
    this.children = new ArrayList<Square>();
    if(this.depth != MAX_DEPTH){
      makeChildren();
    }
  }
  
  void makeChildren(){
    float childSize = this.size / 3.0;
    for(int x = 0; x < 3; x++){
      for(int y = 0; y < 3; y++){
        if(!(x == 1 && y == 1)){
          children.add(new Square(this.topLeft.x + childSize * x, this.topLeft.y + childSize * y, childSize, this.depth + 1));
        }
      }
    }
  }
  
  void draw(){
    fill(0);
    float topLeftXVariant = 100 * (2.0 * noise(noiseX) - 1.0);
    float topLeftYVariant = 100 * (2.0 * noise(noiseY) - 1.0);    
    rect(topLeft.x + topLeftXVariant, topLeft.y + topLeftYVariant, size, size);
    fill(255);
    float childSize = size / 3.0;
    float xVariant = (childSize * MAX_XY_NOISE_RATIO) * (2.0 * noise(noiseX) - 1.0);
    float yVariant = (childSize * MAX_XY_NOISE_RATIO) * (2.0 * noise(noiseY) - 1.0);
    float sizeVariant = (childSize * MAX_SIZE_NOISE_RATIO) * (2.0 * noise(noiseSize) - 1.0);
    rect(topLeft.x + childSize + xVariant, topLeft.y + childSize + yVariant, childSize + sizeVariant, childSize + sizeVariant);
    if(children.size() != 0){
      for(Square child: children){
        child.draw();
      }
    }
  }
  
  void update(){
    noiseX += 0.01;
    noiseY += 0.01;
    noiseSize += 0.01;
    if(children.size() != 0){
      for(Square child: children){
        child.update();
      }
    } 
  }
    
}