# Stepping Through a Fractal Tree

**URL:** https://discourse.processing.org/t/stepping-through-a-fractal-tree/45272
**Category:** Gallery
**Created:** [November 4, 2024, 12:29am UTC](https://discourse.processing.org/t/stepping-through-a-fractal-tree/45272 "2024-11-04T00:29:09Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)
#### Post date: [November 4, 2024, 12:29am UTC](https://discourse.processing.org/t/stepping-through-a-fractal-tree/45272/1 "2024-11-04T00:29:09Z")

</div>

Stepping through a fractal tree using a thread.  
A PGraphic is updated in a thread one line at a time and displayed in draw().

```auto
// 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
  }

```

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/7/7/77fd3b9b7f6d369ef663c3a02d6074625a974775.png)

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/3/c/3c4289c90992ae7c491c47a191914a4d5f410e8d.png)

That was fun!

`:)`

---

<div class="post-metadata">

### Author: ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)
#### Post date: [November 4, 2024, 1:54am UTC](https://discourse.processing.org/t/stepping-through-a-fractal-tree/45272/2 "2024-11-04T01:54:56Z")

</div>

Nice work. Hope to see Turtle Graphics further developed in Processing.
