diff --git a/ring/ring.pde b/ring/ring.pde index 996e528..0dadae0 100644 --- a/ring/ring.pde +++ b/ring/ring.pde @@ -1,68 +1,189 @@ +import peasy.PeasyCam; + class Leaf { PVector pos; + boolean reached = false; + + Leaf(PVector pos) { + this.pos = pos; + } - Leaf() { - pos = PVector.random2D(); + void show() { + fill(0); + noStroke(); + pushMatrix(); + translate(pos.x, pos.y, pos.z); + sphere(1); + popMatrix(); + } + + void reached() { + reached = true; } } class Branch { PVector pos; + Branch parent; + PVector dir; + PVector origDir; + int count; + int len = 5; - Branch(PVector pos) { - this.pos = pos; + Branch(PVector v, PVector d) { + parent = null; + pos = v.copy(); + dir = d.copy(); + origDir = dir.copy(); + } + + Branch(Branch p) { + parent = p; + pos = parent.next(); + dir = parent.dir.copy(); + origDir = dir.copy(); } - Branch(Branch b) { - this.pos = b.pos; + boolean isParent(Branch b, int depth) { + if (this.equals(b)) return true; + if (depth == 1 ||parent == null) return false; + return parent.isParent(b, depth--); + } + + void reset() { + count = 0; + dir = origDir.copy(); + } + + PVector next() { + PVector v = PVector.mult(dir, len); + PVector next = PVector.add(pos, v); + return next; } } class Tree { - ArrayList branches = new ArrayList<>(); - ArrayList leaves = new ArrayList<>(); - + ArrayList branches = new ArrayList(); + ArrayList leaves = new ArrayList(); + Tree() { - for (int i = 0; i < 2000; i++) leaves.add(new Leaf()); - - Branch root = new Branch(new PVector(width/2, height/2)); + makeTorus(); + + Branch root = new Branch(new PVector(300, 0), new PVector(0, -1)); branches.add(root); Branch current = new Branch(root); - - while(!closeEnough(current)) { + + while (!closeEnough(current)) { Branch trunk = new Branch(current); branches.add(trunk); current = trunk; } } + void makeTorus() { + for (int i = 0; i < 200; i++) { + for (int p = 0; p < 90; p++) { + PVector pos = PVector.random3D(); + pos.mult(90); + pos.add(sin(i)*300, cos(i)*300); + leaves.add(new Leaf(pos)); + } + } + } + boolean closeEnough(Branch b) { for (Leaf l : leaves) { - float d = PVector.dist(b.pos, l.pos); - if (d < max_dist) return true; + float d = PVector.dist(b.pos, l.pos); + if (d < max_dist) return true; } return false; } - + void show() { + //for (Leaf l : leaves) l.show(); + for (int i = 0; i < branches.size(); i++) { + Branch b = branches.get(i); + if (b.parent != null) { + strokeWeight(2); + stroke(0); + line(b.pos.x, b.pos.y, b.pos.z, b.parent.pos.x, b.parent.pos.y, b.parent.pos.z); + } + } + } + + 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 != 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); + PVector rand = PVector.random2D(); + rand.setMag(0.3); + b.dir.add(rand); + b.dir.normalize(); + Branch newB = new Branch(b); + branches.add(newB); + b.reset(); + } + } } - void grow() { - Branch closest = null; - PVector closestDir = null; - float record = -1; - + void fuse() { + ArrayList nonparents = new ArrayList(); 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 (closest == null && d <= max_dist) { - closest = b; - closestDir = dir; - record = d; + boolean isnonparent = true; + for (Branch ib : branches) { + if (ib.parent != null && ib.parent.equals(b)) { isnonparent = false; break; } + } + if (isnonparent) nonparents.add(b); + } + for (Branch b : nonparents) { + Branch closest = null; + float record = -1; + for (Branch ib : nonparents) { + if (ib.equals(b)) continue; + PVector dir = PVector.sub(ib.pos, b.pos); + float d = dir.mag(); + if (closest == null || d < record) { + closest = ib; + record = d; + } + } + if (closest != null) { + Branch n = new Branch(b); + n.pos = closest.pos.copy(); + branches.add(n); } } } @@ -71,16 +192,21 @@ class Tree { Tree tree; float min_dist = 5; -float max_dist = 50; +float max_dist = 20; +boolean fused = false; + +PeasyCam cam; void setup() { - size(600, 600); - frameRate(5); + size(600, 600, P3D); + cam = new PeasyCam(this, 500); tree = new Tree(); } void draw() { - background(40); - tree.show(); - tree.grow(); + background(255); + stroke(0); + tree.show(); + if (tree.leaves.size() > 10) tree.grow(); + else if (!fused) { tree.fuse(); fused = true; } } \ No newline at end of file