var treeNum = 4;
var rootNum = 30;
var sum = treeNum + rootNum;
var tree = [];
var turn = [];
function setup() {
createCanvas(windowWidth, windowHeight);
noiseSeed(655);
for (var i = 0; i < sum; i++) {
if (i < rootNum) tree.push(new Tree(true));
else tree.push(new Tree(false));
}
for (var i = 0; i < sum; i++) {
tree[i].initBranch();
}
shuffleNumber();
}
function draw() {
background(50);
for (var i = 0; i < sum; i++) {
tree[turn[i]].run();
}
}
function shuffleNumber() {
var temp;
for (var i = 0; i < sum; i++) {turn.push(i);}
for (var i = turn.length-1; i >= 0; i--) {
var m = int(random(0, i+1));
temp = turn[i];
turn[i] = turn[m];
turn[m] = temp;
}
}
function mousePressed() {
loop();
noiseSeed(655);
for (var i = 0; i < sum; i++) {
tree[i].initBranch();
}
loop(); //I do not know why second loop() is necessary for loop.
}
function keyPressed() {
if (key =='s') saveFrame("####tree.png");
}
var Branch = function(_origin, _angle, _maxLen, _weight, _id) {
this.origin = _origin;
this.angle = _angle;
this.maxLen = _maxLen;
this.len = 0;
this.weight = _weight;
this.isGenerated = false;
this.id = _id;
this.brightness = 1.4;
this.upColor = 50;
this.col =color(205*noise(this.id/100.0)*this.brightness+this.upColor, 255*noise(this.id/100.0)*this.brightness+this.upColor, 255*noise(this.id/100.0)*this.brightness+this.upColor);
};
Branch.prototype.generate = function(id){
var nextOrigin = createVector(0, -this.maxLen);
nextOrigin.rotate(this.angle);
nextOrigin.add(this.origin);
var rGauss = randomGaussian();
var range = 0.2;
var mean = 0.6;
var nextmaxLen = this.maxLen*(mean + rGauss*range) ;
var nextAngle = this.angle + random(-PI/3, PI/3);
var nextWeight = this.weight*random(0.5, 0.8);
return new Branch(nextOrigin, nextAngle, nextmaxLen, nextWeight, id);
};
Branch.prototype.update = function() {
if (this.len < this.maxLen) {
this.len += this.maxLen;
} else {
this.len = this.maxLen;
}
};
Branch.prototype.display = function() {
push();
translate(this.origin.x, this.origin.y);
rotate(this.angle);
strokeWeight(this.weight);
stroke(this.col);
line(0, 0, 0, -this.len);
fill("#0DE0FA");
ellipse(0, -this.len, this.len*0.1, this.len*0.1);
pop();
};
Branch.prototype.isDone = function() {
if (this.len == this.maxLen) return true;
else return false;
};
var Root = function(_origin, _angle, _maxLen, _weight, _id) {
this.origin = _origin;
this.angle = _angle;
this.maxLen = _maxLen;
this.len = 0;
this.weight = _weight;
this.isGenerated = false;
this.id = _id;
this.brightness = 1.3;
this.upColor = 50;
this.col =color(205*noise(this.id/100.0)*this.brightness+this.upColor, 255*noise(this.id/100.0)*this.brightness+this.upColor, 255*noise(this.id/100.0)*this.brightness+this.upColor);
};
Root.prototype.generate = function(id){
var nextOrigin = createVector(0, this.maxLen);
nextOrigin.rotate(this.angle);
nextOrigin.add(this.origin);
var rGauss = randomGaussian();
var range = 0.3;
var mean = 0.6;
var nextmaxLen = this.maxLen*(mean + rGauss*range) ;
var nextAngle = this.angle + random(-PI/5, PI/5);
var nextWeight = this.weight*random(0.4, 0.7);
return new Root(nextOrigin, nextAngle, nextmaxLen, nextWeight, id);
};
Root.prototype.update = function() {
if (this.len < this.maxLen) {
this.len += this.maxLen;
} else {
this.len = this.maxLen;
}
};
Root.prototype.display = function() {
push();
translate(this.origin.x, this.origin.y);
rotate(this.angle);
strokeWeight(this.weight);
stroke(this.col);
line(0, 0, 0, this.len);
pop();
};
Root.prototype.isDone = function() {
if (this.len == this.maxLen) return true;
else return false;
};
var Tree = function(_isRoot) {
this.branches = [];
this.branchId = 0;
this.origin;
this.isRoot = _isRoot;
this.x, this.y;
this.initBranch();
this.history = 0;
this.lastLen = 0;
this.len = 0;
};
Tree.prototype.initBranch = function() {
this.branches = [];
this.history = 0;
this.lastLen = 0;
this.len = 0;
if (!this.isRoot) {
this.x = width/2 + random(-13, 13);
this.y = height*0.95;
} else {
this.x = width/2;
this.y = height*0.95 + random(-20,20) + 0;
}
this.origin = createVector(this.x, this.y);
this.branchId = 0;
if (!this.isRoot) {
this.branches.push(new Branch(this.origin, random(-PI/50, PI/50), random(80, 150), random(5, 30), this.branchId));
} else {
this.branches.push(new Root(this.origin, random(-PI/3, PI/3), random(0, 60), random(10, 1), this.branchId));
}
}
Tree.prototype.updateBranch = function() {
for (var i = 0; i < this.branches.length; i++) {
if (this.branches[i].isDone() && !this.branches[i].isGenerated) {
this.branches[i].isGenerated = true;
for (var j = 0; j < int(random(2, 5)); j++) {
if (!this.isRoot && this.branches[i].maxLen>10 && this.branches.length < 1800) {
this.branches.push(this.branches[i].generate(this.branchId));
this.branchId ++;
} else {
if (this.branches.length < 20 && this.branches[i].maxLen>10) {
this.branches.push(this.branches[i].generate(this.branchId));
this.branchId ++;
}
}
}
}
}
}
Tree.prototype.run = function() {
this.len = this.branches.length;
if(this.len == this.lastLen) this.history++;
else this.history = 0;
if(this.history > 10) {
noLoop();
}
this.updateBranch();
for (var i = 0; i < this.branches.length; i++) {
this.branches[i].update();
this.branches[i].display();
}
this.lastLen = this.len;
}