Skip to content

Instantly share code, notes, and snippets.

@PatrickMurphy
Last active February 14, 2017 19:35
Show Gist options
  • Save PatrickMurphy/bc544d886e5a31d2cf928d548f7bf0e5 to your computer and use it in GitHub Desktop.
Save PatrickMurphy/bc544d886e5a31d2cf928d548f7bf0e5 to your computer and use it in GitHub Desktop.
Brownian Fractal Tree in Processing (Java)
class BrownianPartical {
PVector position;
float radius;
color fill;
BrownianPartical(PVector pos){
this(pos, color(255));
}
BrownianPartical(PVector pos, color c){
position = pos;
fill = c;
radius = random(1,5);
}
void display(){
stroke(fill);
strokeWeight(radius);
point(position.x,position.y);
}
}
import java.util.concurrent.CopyOnWriteArrayList;
CopyOnWriteArrayList<BrownianPartical> points;
CopyOnWriteArrayList<BrownianWalker> walkers;
boolean realtime_mode = true;
int agent_count = 50;
int collide_count = 0;
int lost_count = 0;
int last_frame_collide_count = 0;
int target_collisions = 100;
boolean generating = false;
void setup() {
size(400, 400);
points = new CopyOnWriteArrayList<BrownianPartical>();
points.add(new BrownianPartical(new PVector(width/2, height/2)));
walkers = new CopyOnWriteArrayList<BrownianWalker>();
if (realtime_mode) {
agent_count = 750;
}
for (int i = 0; i<agent_count; i++) {
walkers.add(new BrownianWalker());
}
if (!realtime_mode) {
thread("calculateBrownianTree");
}
//println(dist(5, 5, 7, 7));
}
void mousePressed() {
if (!realtime_mode && !generating) {
target_collisions += 100;
thread("calculateBrownianTree");
}
}
void calculateBrownianTree() {
if (!realtime_mode) {
generating = true;
while (collide_count <= target_collisions) {
for (BrownianWalker walker : walkers) {
walker.update();
}
}
generating = false;
}
}
void draw() {
background(35);
fill(255, 0, 0);
stroke(255, 0, 0);
text("Lost: "+lost_count, 10, 10);
text("Collide: "+collide_count, 10, 20);
text("Time: " + floor((millis()/1000.0)/60) + " Min " + floor((millis()/1000.0)%60) + " Seconds", 10, 30);
stroke(255);
for (BrownianPartical point : points) {
point.display();
}
if (realtime_mode) {
for (BrownianWalker walker : walkers) {
walker.update();
walker.display();
}
}
if((collide_count)%50 == 0 && last_frame_collide_count<collide_count){
last_frame_collide_count = collide_count;
saveFrame("line-######.png");
}
}
class BrownianWalker {
PVector position;
float radius;
boolean behavior_bounce = true;
PVector velocity;
BrownianWalker() {
// random position
radius =random(1,5);
velocity = PVector.random2D();
setRandomPosition(true);
}
void update() {
if (behavior_bounce) {
if (random(100)>50) {
velocity = PVector.random2D();
}
position.add(velocity);
} else {
position.add(PVector.random2D());
}
if (position.x > 1 && position.x < width-1 && position.y > 1 && position.y < height-1) {
for (BrownianPartical point : points) {
if (dist(point.position.x, point.position.y, position.x, position.y)<=sqrt(point.radius+radius)*1.5) {
collide();
}
}
} else {
// if(behavior_bounce){
// PVector normal =
// velocity = velocity.sub()
// }else{
lost_count++;
collide(false); // edge hit
// }
}
}
void display() {
strokeWeight(radius);
point(position.x, position.y);
}
void collide() {
collide(true);
}
void collide(boolean add) {
//println("collide");
if (add) {
collide_count++;
points.add(new BrownianPartical(position, color(random(0, 255), random(0, 255), random(0, 255))));
}
setRandomPosition();
}
void setRandomPosition() {
setRandomPosition(false);
}
void setRandomPosition(boolean init) {
//position = new PVector(random(width*.2,width-(width*.2)), random(height*.2,height-(height*.2)));
// add if not near point
velocity = PVector.random2D();
position = new PVector(random(width), random(height));
if (points.size()>0 && !init) {
for (BrownianPartical point : points) {
if (dist(point.position.x, point.position.y, position.x, position.y)<=(point.radius+radius)*3) {
setRandomPosition();
break;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment