203 lines
4.0 KiB
Plaintext
203 lines
4.0 KiB
Plaintext
import peasy.PeasyCam;
|
|
|
|
static int RING_SIZE = 500;
|
|
static int RING_WIDTH = 120;
|
|
|
|
class Leaf {
|
|
PVector pos;
|
|
boolean reached = false;
|
|
|
|
Leaf(PVector pos) {
|
|
this.pos = pos;
|
|
}
|
|
|
|
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 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();
|
|
}
|
|
|
|
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<Branch> branches = new ArrayList<Branch>();
|
|
ArrayList<Leaf> leaves = new ArrayList<Leaf>();
|
|
|
|
Tree() {
|
|
makeTorus();
|
|
|
|
Branch root = new Branch(new PVector(RING_SIZE, 0), 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;
|
|
}
|
|
}
|
|
|
|
void makeTorus() {
|
|
for (int i = 0; i < 350; i++) {
|
|
for (int p = 0; p < 90; p++) {
|
|
PVector pos = PVector.random3D();
|
|
pos.x = 0;
|
|
pos.y = 0;
|
|
pos.mult(RING_WIDTH);
|
|
pos.add(sin(i)*RING_SIZE, cos(i)*RING_SIZE);
|
|
leaves.add(new Leaf(pos));
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean closeEnough(Branch b) {
|
|
int i = 0;
|
|
for (Leaf l : leaves) {
|
|
float d = PVector.dist(b.pos, l.pos);
|
|
if (d < max_dist) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void show() {
|
|
//for (Leaf l : leaves) l.show();
|
|
int size = branches.size();
|
|
for (int i = 0; i < 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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Tree tree;
|
|
|
|
float min_dist = 5;
|
|
float max_dist = 20;
|
|
|
|
PeasyCam cam;
|
|
|
|
void setup() {
|
|
size(600, 600, P3D);
|
|
cam = new PeasyCam(this, 500);
|
|
tree = new Tree();
|
|
}
|
|
|
|
void drawCircles() {
|
|
noFill();
|
|
strokeWeight(4);
|
|
pushMatrix();
|
|
translate(0, 0, RING_WIDTH);
|
|
ellipse(0, 0, RING_SIZE*2, RING_SIZE*2);
|
|
popMatrix();
|
|
|
|
pushMatrix();
|
|
translate(0, 0, -RING_WIDTH);
|
|
ellipse(0, 0, RING_SIZE*2, RING_SIZE*2);
|
|
popMatrix();
|
|
}
|
|
|
|
void draw() {
|
|
background(255);
|
|
stroke(0);
|
|
tree.show();
|
|
tree.grow();
|
|
drawCircles();
|
|
} |