Stepping through a fractal tree using a thread.
A PGraphic is updated in a thread one line at a time and displayed in draw().
// Stepping through a Fractal Tree
// A PGraphic is updated in a thread one line at a time and displayed in draw()
//
// Author: GLV
// Date: 2024-09-29
// Code from references below were used and adapted.
// Code references:
// https://www.geeksforgeeks.org/y-fractal-tree-in-python-using-turtle/
// Turtle Graphics in Processing
// Natalie Freed, February 2013
// https://gist.github.com/nataliefreed/8483050
PGraphics pg;
PVector loc; //current location
float orientation; //current orientation
boolean penDown = false; // penDown (to draw) or !penDown (do not draw)
boolean bgi = true; // Background (once only)
boolean db = true; // Debug information with print()
int level; // level (nesting/branches)
int count = 0; // counter (total lines drawn)
int lfCnt = 0; // leaf counter
int lngth; // length of branch
void setup()
{
size(700, 600);
if (bgi)
{
background(0);
bgi = false;
}
pg = createGraphics(width, height);
// Initialize
loc = new PVector(width/2, height-60); //starting position is at center
orientation = radians(90); //starting orientation is at 90 degrees
count = 0;
lngth = 90;
level = 8;
lfCnt = 0;
frameRate(240); // 1/frameRate (period) < delay 4.2ms < 10ms (in line function)
thread("requestData");
noLoop();
}
//*****************************************************************
void draw()
{
image(pg, 0, 0);
}
//*****************************************************************
void branch(float len, int th, int lev)
{
float a = radians(th);
if (lev > 0)
{
lev--;
forward(len, lev);
right(a);
th = th + choice(-5, 5);
float rv = 0.1; //Random values
float swl = 0.8 + random(-rv, rv);
branch(swl*len, th, lev);
left(2*a);
float swr = 0.8 + random(-rv, rv);
branch(swr*len, th, lev);
// Do not draw when returning to branch point
penDown = false;
right(a);
forward(-len, lev);
penDown = true;
}
}
//*****************************************************************
void requestData()
{
pg.beginDraw();
pg.background(0, 5);
pg.strokeWeight(level);
pg.stroke(255);
pg.line(loc.x, loc.y, loc.x, loc.y - lngth);
pg.endDraw();
penDown = true;
branch(lngth, 25, level);
delay(1000); // Enjoy the generated fractal!
frameCount = 0;
redraw(); // loop() skips a line!
}
//*****************************************************************
// Toggle numbering of branches
void keyPressed()
{
db = !db;
}
//*****************************************************************
// Modified:
void forward(float pixels, int lev) //calculate positions when moving forward
{
PVector start = loc;
PVector end = PVector.add(loc, polar(pixels, orientation));
loc = end;
if(penDown)
{
line(start, end, lev);
redraw();
}
}
//*****************************************************************
// Original (unchanged):
void left(float theta) //calculate new orientation
{
orientation += theta;
}
//*****************************************************************
// Original (unchanged):
void right(float theta) //calculate new orientation
{
orientation -= theta;
}
//*****************************************************************
// Modified:
// Only draw a line if penDown
void line(PVector a, PVector b, int lev) //new line function with PVectors. used by forward function
{
// Update PGraphic frame
pg.beginDraw();
if (lev == 0)
{
pg.stroke(0, 255, 0);
pg.strokeWeight(2);
lfCnt++; // leaf counter
// Shows leaf count at end of leaf
if (db)
{
pg.textAlign(CENTER, CENTER);
PVector txtLoc = loc.copy();
PVector ln = b.copy().sub(a.copy());
txtLoc.add(ln.normalize().mult(10));
pg.push();
pg.stroke(1);
pg.fill(255);
pg.text(lfCnt, txtLoc.x, txtLoc.y);
pg.pop();
}
}
else
{
pg.stroke(255-255/(lev+1));
pg.strokeWeight(lev+2);
}
count++;
pg.line(a.x, a.y, b.x, b.y);
delay(10); // greater than 1/frameRate
pg.endDraw();
}
//*****************************************************************
// Original (unchanged):
PVector polar(float r, float theta) //converts an angle and radius into a vector
{
return new PVector(r*cos(theta), r*sin(-theta)); // negate y for left handed coordinate system
}
That was fun!
:)