Mod:Coding Challenge #17: Fractal Trees - Space Colonization (revise)
昨日は飲んでからプログラムを書いたので、樹形を描画する部分の処理の一部が抜けた分、描画が進まない状態だった。改めて確認して修正したものをアップする。OpenProcessingでは動かなかったので、GIFで。
Tree tree; float min_dist = 5; float max_dist = 50; void setup() { size(800, 800); colorMode(HSB, 360, 100, 100, 100); tree = new Tree(); } void draw() { background(220, 20, 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 < 2000; 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++; } } for (int i = leaves.size()-1; i >= 0; i--) { if (leaves.get(i).reached) { leaves.remove(i); } } for (int i = branches.size()-1; i >= 0; i--) { Branch b = branches.get(i); if (b.count > 0) { b.dir.div(b.count); b.dir.normalize(); Branch newB = new Branch(b); branches.add(newB); b.reset(); } } } 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); } }