日常の進捗

主に自分のための,行為とその習慣化の記録

Mod:Coding Challenge #17: Fractal Trees - Space Colonization

f:id:takawo:20170916000027p:plain

コード

Tree tree;

float min_dist = 15;
float max_dist = 5;

void setup() {
  size(960, 540);
  colorMode(HSB, 360, 100, 100, 100);
  tree = new Tree();
}

void draw() {
  background(0, 0, 33);
  tree.draw();
  tree.grow();
}

class Tree {
  ArrayList<Branch> branches = new ArrayList<Branch>();
  ArrayList<Leaf> leaves = new ArrayList<Leaf>();  
  Tree() {
    for (int i = 0; i < 1000; i++) {
      leaves.add(new Leaf());
    }
    Branch root = new Branch(new PVector(width/2, height), new PVector(0, -1));
    branches.add(root);
    Branch current = new Branch(root);
    while (!closeEnough(current)) {
      Branch trunk = new Branch(current);
      branches.add(trunk);
      current = trunk;
    }
  }
  boolean closeEnough(Branch b) {
    for (Leaf l : leaves) {
      float d = PVector.dist(b.pos, l.pos);
      if (d < max_dist) {
        return true;
      }
    }
    return false;
  }

  void grow() {
    for (Leaf l : leaves) {
      Branch closest = null;
      PVector closestDir = null;
      float record = -1;

      for (Branch b : branches) {
        PVector dir = PVector.sub(l.pos, b.pos);
        float d = dir.mag();
        if (d < min_dist) {
          l.reached();
          closest = null;
          break;
        } else if (d > max_dist) {
        } else if (closest == null || d < record) {
          closest = b;
          closestDir = dir;
          record = d;
        }
      }
      if (closest != null) {
        closestDir.normalize();
        closest.dir.add(closestDir);
        closest.count++;
      }
    }
  }

  void draw() {
    for (Leaf l : leaves) {
      l.draw();
    }
    for (Branch b : branches) {
      if (b.parent != null) {
        stroke(0, 0, 100);
        line(b.pos.x, b.pos.y, b.parent.pos.x, b.parent.pos.y);
      }
    }
  }
}

class Branch {
  Branch parent;
  PVector pos;
  PVector dir;
  int count = 0;
  PVector saveDir;
  float len = 5;

  Branch(PVector _pos, PVector _dir) {
    parent = null;
    pos = _pos.copy();
    dir = _dir.copy();
    saveDir = dir.copy();
  }
  Branch(Branch _parent) {
    parent = _parent;
    pos = parent.next();
    dir = parent.dir.copy();
    saveDir = dir.copy();
  }

  void reset() {
    count = 0;
    dir = saveDir.copy();
  }
  PVector next() {
    PVector v = PVector.mult(dir, len);
    PVector next = PVector.add(pos, v);
    return next;
  }
}

class Leaf {
  PVector pos;
  boolean reached = false;
  float d = 4;

  Leaf() {
    pos = PVector.random2D();
    pos.mult(random(width/2));
    pos.x += width/2;
    pos.y += height/2;
  }

  void reached() {
    reached = true;
  }

  void draw() {
    fill(0, 0, 100);
    noStroke();
    ellipse(pos.x, pos.y, d, d);
  }
}

リファレンス

www.youtube.com