Created
May 27, 2016 16:36
-
-
Save shiffman/c8d08f9b796abe9ecf98ea6b5fd9cb1e to your computer and use it in GitHub Desktop.
Space Colonization Attempt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Tree tree; | |
float min_dist = 5; | |
float max_dist = 250; | |
void setup() { | |
size(180, 300); | |
tree = new Tree(); | |
} | |
void draw() { | |
background(51); | |
tree.show(); | |
tree.grow(); | |
} | |
class Branch { | |
Branch parent; | |
PVector pos; | |
PVector dir; | |
int count = 0; | |
PVector saveDir; | |
float len = 5; | |
Branch(PVector v, PVector d) { | |
parent = null; | |
pos = v.copy(); | |
dir = d; | |
saveDir = dir.copy(); | |
} | |
Branch(Branch p) { | |
parent = p; | |
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 Tree { | |
ArrayList<Branch> branches = new ArrayList<Branch>(); | |
ArrayList<Leaf> leaves = new ArrayList<Leaf>(); | |
Tree() { | |
for (int i = 0; i < 400; 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(); | |
break; | |
} else if (d > max_dist) { | |
break; | |
} 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 show() { | |
for (Leaf l : leaves) { | |
l.show(); | |
} | |
for (Branch b : branches) { | |
if (b.parent != null) { | |
stroke(255); | |
line(b.pos.x, b.pos.y, b.parent.pos.x, b.parent.pos.y); | |
} | |
} | |
} | |
} | |
class Leaf { | |
PVector pos; | |
boolean reached = false; | |
Leaf() { | |
pos = new PVector(random(10, width-10), random(10, height-40)); | |
} | |
void reached() { | |
reached = true; | |
} | |
void show() { | |
fill(255); | |
noStroke(); | |
ellipse(pos.x, pos.y, 4, 4); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment