int MAX_DEPTH = 5;
float MAX_RADIAN_SPEED = PI / 64;
Circle root;
void setup(){
size(500, 500);
smooth();
frameRate(24);
noStroke();
root = new Circle();
}
void draw(){
colorMode(RGB, 256);
fill(0);
background(0);
root.draw();
root.update();
}
class Circle{
float positionRadious;
float positionRadian;
float positionRadianSpeed;
float circleRadious;
float hue;
ArrayList<Circle> children;
int depth;
Circle(){
positionRadious = sqrt(sq(width) * 2.0) / 2.0;
positionRadian = PI / 4.0;
positionRadianSpeed = 0.0;
circleRadious = width / 2.0;
depth = 0;
hue = random(360);
children = new ArrayList<Circle>();
makeChildren();
}
Circle(float positionRadious,float positionRadian, float positionRadianSpeed, int depth){
this.positionRadious = positionRadious;
this.positionRadian = positionRadian;
this.positionRadianSpeed = positionRadianSpeed;
this.circleRadious = positionRadious;
this.depth = depth;
hue = random(360);
children = new ArrayList<Circle>();
makeChildren();
}
void makeChildren(){
if(depth != MAX_DEPTH){
float nextPositionRadious = circleRadious / 2.0;
float nextPositionRadian = random(TWO_PI);
float nextPositionRadianSpeed = random(MAX_RADIAN_SPEED * 2) - MAX_RADIAN_SPEED;
children.add(new Circle(nextPositionRadious, nextPositionRadian, nextPositionRadianSpeed, depth + 1));
children.add(new Circle(nextPositionRadious, nextPositionRadian + PI, nextPositionRadianSpeed, depth + 1));
}
}
void draw(){
float x = positionRadious * cos(positionRadian);
float y = positionRadious * sin(positionRadian);
colorMode(HSB, 360, 100, 100);
fill(hue, 100, 100);
arc(x, y, circleRadious * 2, circleRadious * 2, 0, TWO_PI);
if(children.size() != 0){
for(Circle child: children){
pushMatrix();
translate(x, y);
child.draw();
popMatrix();
}
}
}
void update(){
positionRadian += positionRadianSpeed;
if(positionRadian < 0){
positionRadian += TWO_PI;
} else if(positionRadian >= TWO_PI){
positionRadian -= TWO_PI;
}
for(Circle child: children){
child.update();
}
}
}