Daily Creative Coding

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

成長する木々

f:id:aa_debdeb:20151012001505j:plain
/**
* Branching Trees
* 
* @author aa_debdeb
* @date 2015/10/12
*/


float NEW_TREE_PROB = 0.05;
float MAX_BRANCH_PROB = 0.5;
float MIN_DYING_PROB = 0.05;
float BRANCH_PROB_DIFF = 0.03;
float DYKING_PROB_DIFF = 0.05;
float MAX_BRANCH_GROWTH = 2.0;

ArrayList<Tree> trees;

void setup(){
  size(500, 500);
  smooth();
  frameRate(24);
  background(255);
  
  trees = new ArrayList<Tree>();
  trees.add(new Tree());
}

void draw(){
  if(random(1) < NEW_TREE_PROB){
    trees.add(new Tree());
  }
  
  for(Tree tree: trees){
    tree.grow();
  }
  
  ArrayList<Tree> newTrees = new ArrayList<Tree>();
  for(Tree tree: trees){
    if(!tree.isDead()){
      newTrees.add(tree);
    }
  }
  trees = newTrees;
}

class Tree{
  ArrayList<Branch> activeBranches;
  
  Tree(){
    activeBranches = new ArrayList<Branch>();
    activeBranches.add(new Branch());  
  }
  
  boolean isDead(){
    if(activeBranches.size() == 0){
      return true;
    } else {
      return false;
    }
  }
  
  void grow(){
    
    ArrayList<Branch> dyingBranches = new ArrayList<Branch>();
    for(Branch b: activeBranches){
      if(random(1) < b.dyingProb){
        dyingBranches.add(b);    
      }
    }
    for(Branch b: dyingBranches){
      activeBranches.remove(b);
    }
    
    ArrayList<Branch> newBranches = new ArrayList<Branch>();
    for(Branch b: activeBranches){
      if(random(1) < b.branchProb){
        newBranches.add(new Branch(b));    
      }
    }
    for(Branch b: newBranches){
      activeBranches.add(b);
    }
    
    for(Branch b: activeBranches){
      b.grow();
    }
  }
    
}

class Branch{
  
  PVector tip;
  PVector growth;
  float grey;
  float branchProb;
  float dyingProb;
  
  Branch(){
    tip = new PVector(random(width), random(height));
    growth = new PVector(random(2) - 1, random(2) - 1);
    growth.normalize();
    growth.mult(MAX_BRANCH_GROWTH);
    grey = random(255);
    branchProb = random(MAX_BRANCH_PROB);
    dyingProb = random(MIN_DYING_PROB);
  }
  
  Branch(Branch b){
    tip = new PVector(b.tip.x, b.tip.y);
    growth = new PVector(b.growth.x, b.growth.y);
    growth.div(sqrt(2));
    growth.rotate(random(PI) - HALF_PI);
    grey = b.grey;
    branchProb = b.branchProb - BRANCH_PROB_DIFF;
    dyingProb = b.dyingProb + DYKING_PROB_DIFF;
  }
  
  void grow(){
    stroke(grey);
    strokeWeight(1);
    PVector newTip = PVector.add(tip, growth);
    line(tip.x, tip.y, newTip.x, newTip.y);
    tip = newTip;
  }
}