 # Recursive Tree without using rotate()

This might be a weird question , but here goes:
Would it be possible to draw a Recursive Tree WITHOUT using `rotate()`?

I ask because I am preparing a couple of interactive projects where I use Processing to control a AxiDraw plotter in respons to users drawing on paper seen through top-dow web-camera + openCV. It seems like I might run into trouble with rotate(), since the AxiDraw needs specific coordinates to move to, and I cannot rotate the paper Below is Shiffmans example of a recursive tree using rotate. Could it be done with PVectors instead?

``````float theta;

void setup() {
size(640, 360);
}

void draw() {
background(0);
frameRate(30);
stroke(255);
// Let's pick an angle 0 to 90 degrees based on the mouse position
float a = (mouseX / (float) width) * 90f;
// Start the tree from the bottom of the screen
translate(width/2,height);
// Draw a line 120 pixels
line(0,0,0,-120);
// Move to the end of that line
translate(0,-120);
// Start the recursive branching!
branch(120);

}

void branch(float h) {
// Each branch will be 2/3rds the size of the previous one
h *= 0.66;

// All recursive functions must have an exit condition!!!!
// Here, ours is when the length of the branch is 2 pixels or less
if (h > 2) {
pushMatrix();    // Save the current state of transformation (i.e. where are we now)
rotate(theta);   // Rotate by theta
line(0, 0, 0, -h);  // Draw the branch
translate(0, -h); // Move to the end of the branch
branch(h);       // Ok, now call myself to draw two new branches!!
popMatrix();     // Whenever we get back here, we "pop" in order to restore the previous matrix state

// Repeat the same thing, only branch off to the "left" this time!
pushMatrix();
rotate(-theta);
line(0, 0, 0, -h);
translate(0, -h);
branch(h);
popMatrix();
}
}
``````
1 Like

That’s possible

Without being at a real computer:

get rid of rotate and calculate the new x,y using cos and sin.

probably pass the new x,y as a Parameter to the function

I attempted to do it with PVectors, but yeah perhaps it would be easier with just cos and sin? But I guess I should pass the angle to the function too or…?

PVector and cos go together well, you store the cos sin results in a PVector

Yeah, angle too I guess

Here is the recursive tree without using rotate hope it helps you with your own project.

``````float theta;

void setup() {
size(640, 360);
}

void draw() {
background(0);
frameRate(30);
stroke(255);
// Let's pick an angle 0 to 95 degrees based on the mouse position
float a = (mouseX / (float) width) * 95f;
// then cap it at 90 degrees
a = min(a, 90);
// Start the tree from the bottom of the screen
translate(width/2, height);
// Draw a line 120 pixels
line(0, 0, 0, -120);
// Move to the end of that line
translate(0, -120);
// Start the recursive branching!
branch(new PVector(0, 0), -PI/2, theta, 120);
}

void branch(PVector parent, float branch_angle, float delta_angle, float h) {
// Each branch will be 2/3rds the size of the previous one
h *= 0.66;
if (h > 2) {
float ccw_angle, cw_angle, delta_x, delta_y;
// Left branch
// Counter-Clockwise branch
pushMatrix();
translate(parent.x, parent.y);
ccw_angle = branch_angle - delta_angle;
delta_x = h * cos(ccw_angle);
delta_y = h * sin(ccw_angle);
line(0, 0, delta_x, delta_y);
popMatrix();
branch(new PVector(parent.x + delta_x, parent.y + delta_y), ccw_angle, delta_angle, h);
// Right branch
// Clockwise branch
pushMatrix();
translate(parent.x, parent.y);
cw_angle = branch_angle + delta_angle;
delta_x = h * cos(cw_angle);
delta_y = h * sin(cw_angle);
line(0, 0, delta_x, delta_y);
popMatrix();
branch(new PVector(parent.x + delta_x, parent.y + delta_y), cw_angle, delta_angle, h);
}
}

``````
4 Likes

It is possible to remove all matrix operations from the recursive method and use absolute coordinates instead.
Replace the method with

``````void branch(PVector parent, float branch_angle, float delta_angle, float h) {
// Each branch will be 2/3rds the size of the previous one
h *= 0.66;
if (h > 2) {
float ccw_angle, cw_angle, delta_x, delta_y;
// Left branch
// Counter-clockwise branch
ccw_angle = branch_angle - delta_angle;
delta_x = h * cos(ccw_angle);
delta_y = h * sin(ccw_angle);
line(parent.x, parent.y, parent.x + delta_x, parent.y + delta_y);
branch(new PVector(parent.x + delta_x, parent.y + delta_y), ccw_angle, delta_angle, h);
// Right branch
// Clockwise branch
cw_angle = branch_angle + delta_angle;
delta_x = h * cos(cw_angle);
delta_y = h * sin(cw_angle);
line(parent.x, parent.y, parent.x + delta_x, parent.y + delta_y);
branch(new PVector(parent.x + delta_x, parent.y + delta_y), cw_angle, delta_angle, h);
}
}
``````
2 Likes

Thanks so much @quark! This is perfect 1 Like