wip: i might be getting there

This commit is contained in:
2017-11-27 18:53:22 +01:00
parent e85e453f2f
commit 359129040d

View File

@@ -1,68 +1,189 @@
import peasy.PeasyCam;
class Leaf { class Leaf {
PVector pos; PVector pos;
boolean reached = false;
Leaf(PVector pos) {
this.pos = pos;
}
Leaf() { void show() {
pos = PVector.random2D(); fill(0);
noStroke();
pushMatrix();
translate(pos.x, pos.y, pos.z);
sphere(1);
popMatrix();
}
void reached() {
reached = true;
} }
} }
class Branch { class Branch {
PVector pos; PVector pos;
Branch parent;
PVector dir;
PVector origDir;
int count;
int len = 5;
Branch(PVector pos) { Branch(PVector v, PVector d) {
this.pos = pos; 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) { boolean isParent(Branch b, int depth) {
this.pos = b.pos; 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 { class Tree {
ArrayList<Branch> branches = new ArrayList<>(); ArrayList<Branch> branches = new ArrayList<Branch>();
ArrayList<Leaf> leaves = new ArrayList<>(); ArrayList<Leaf> leaves = new ArrayList<Leaf>();
Tree() { Tree() {
for (int i = 0; i < 2000; i++) leaves.add(new Leaf()); makeTorus();
Branch root = new Branch(new PVector(width/2, height/2)); Branch root = new Branch(new PVector(300, 0), new PVector(0, -1));
branches.add(root); branches.add(root);
Branch current = new Branch(root); Branch current = new Branch(root);
while(!closeEnough(current)) { while (!closeEnough(current)) {
Branch trunk = new Branch(current); Branch trunk = new Branch(current);
branches.add(trunk); branches.add(trunk);
current = 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) { boolean closeEnough(Branch b) {
for (Leaf l : leaves) { for (Leaf l : leaves) {
float d = PVector.dist(b.pos, l.pos); float d = PVector.dist(b.pos, l.pos);
if (d < max_dist) return true; if (d < max_dist) return true;
} }
return false; return false;
} }
void show() { 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() { void fuse() {
Branch closest = null; ArrayList<Branch> nonparents = new ArrayList<Branch>();
PVector closestDir = null;
float record = -1;
for (Branch b : branches) { for (Branch b : branches) {
PVector dir = PVector.sub(l.pos, b.pos); boolean isnonparent = true;
float d = dir.mag(); for (Branch ib : branches) {
if (d < min_dist) { if (ib.parent != null && ib.parent.equals(b)) { isnonparent = false; break; }
l.reached(); }
closest = null; if (isnonparent) nonparents.add(b);
break; }
} else if (closest == null && d <= max_dist) { for (Branch b : nonparents) {
closest = b; Branch closest = null;
closestDir = dir; float record = -1;
record = d; 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; Tree tree;
float min_dist = 5; float min_dist = 5;
float max_dist = 50; float max_dist = 20;
boolean fused = false;
PeasyCam cam;
void setup() { void setup() {
size(600, 600); size(600, 600, P3D);
frameRate(5); cam = new PeasyCam(this, 500);
tree = new Tree(); tree = new Tree();
} }
void draw() { void draw() {
background(40); background(255);
tree.show(); stroke(0);
tree.grow(); tree.show();
if (tree.leaves.size() > 10) tree.grow();
else if (!fused) { tree.fuse(); fused = true; }
} }