日常の進捗

行為と記録とその習慣化

Mod:Coding Challenge #15: Fractal Trees - Object Oriented

前回の続き。p5.jsで書かれているものを見ながらProcessingで、クラスベースで書くという感じ。葉っぱも最後に落ちるようになっていたものもクラスに定義して書いてみたくらい。クリックすると枝が増えて、所定回数以上になると葉っぱが落ちるようなもの。OpenProcessingにあげるときにPVectorのcopy()なんかが使えなかったりするので書き換えたりしている。

実際毎フレームArrayListをクリアしながら、マウスの位置から計算する枝の長さと回転角度、階層だけで描画し直すほうがいいのかもしれないとか、所定回数以上になったら、ArrayListをクリアしてとか色々ある。前回より微妙な感じになった気がするが、まだ続くので次に行く。

ArrayList<Branch> tree;
ArrayList<Leaf> leaves;
int count = 0;

void setup() {
  size(960, 540);
  colorMode(HSB, 360, 100, 100);
  tree = new ArrayList<Branch>();
  leaves = new ArrayList<Leaf>();
  PVector begin = new PVector(width/2, height);
  PVector end = new PVector(width/2, height-100);
  Branch root = new Branch(begin, end);
  tree.add(root);
}

void draw() {
  background(220, 20, 20);
  for (Branch b : tree) {
    b.draw();
    //b.jitter();
  }
  for (Leaf l : leaves) {
    l.draw();
  }
}

void mousePressed(){
  for (int i = tree.size() - 1; i >= 0; i--) {
    Branch b = tree.get(i);
    if (!b.isFinished && count < 8) {
      tree.add(b.branchA());
      tree.add(b.branchB());
    }
    b.isFinished = true;
  }
  count++;
  if (count == 6) {
    for (Branch b : tree) {
      if (b.isFinished) {
        Leaf leaf = new Leaf(new PVector(b.end.x,b.end.y));
        leaves.add(leaf);
      }
    }
  }
}

class Branch {
  PVector begin;
  PVector end;
  Boolean isFinished;
  Branch(PVector _begin, PVector _end) {
    begin = _begin;
    end = _end;
    isFinished = false;
  }
  void jitter() {
    end = new PVector(random(-1, 1), random(-1, 1));
  }
  void draw() {
    stroke(0, 0, 100);
    line(begin.x, begin.y, end.x, end.y);
  }

  Branch branchA() {
    float theta = map(mouseX, 0, width, -PI/2, PI/2);
    float ratio = map(mouseY, 0, height, 0.9,0.5);
    PVector dir = PVector.sub(end, begin);
    dir.rotate(theta);
    dir.mult(ratio);
    PVector newEnd = PVector.add(end, dir);
    Branch b = new Branch(end, newEnd);
    return b;
  }
  Branch branchB() {
    float theta = map(mouseX, 0, width, -PI/2, PI/2);
    float ratio = map(mouseY, 0, height, 0.9, 0.5);
    PVector dir = PVector.sub(end, begin);
    dir.rotate(-theta);
    dir.mult(ratio);
    PVector newEnd = PVector.add(end, dir);
    Branch b = new Branch(end, newEnd);
    return b;
  }
}

class Leaf {
  PVector pos;
  Leaf(PVector _pos) {
    pos = _pos;
  }

  void draw() {
    fill(30, 80, 100);
    noStroke();
    ellipse(pos.x, pos.y, 8, 8);
    pos.y += random(0, 2);
  }
}

リファレンス