How to pace the appearance of recursion objects?

Hello all,
This follows up on my previous post still associated with a fractal project Im currently working on.
I am aware that the following question may involve arraylists of which Im not yet familiar with, Im hoping to get there pretty soon but I would appreciate some guidance on how to make the recursion objects appear one after the other…
Thanks!

PShape s;  // The PShape object - Cube
int a = 500;  // Declare variable - Radious Cube
float b = a * sqrt(3) / 2; // Height of triangle
float c = a * 2 / 3; // Circle02 Radious - 7Days of Creation

float f = c * cos(radians(30));
float g = c * cos(radians(60));


void setup() {
   size(1920, 1280);
   background(255);
   stroke(0); 
   strokeWeight(1);
   frameRate(50);
   
  s = createShape();  //Cube Outline
  s.beginShape();
  s.noFill();
  s.stroke(0);
  s.vertex(width/2, height/2-a);
  s.vertex(width/2+b, height/2-a/2);
  s.vertex(width/2+b, height/2+a/2);
  s.vertex(width/2, height/2+a);
  s.vertex(width/2-b, height/2+a/2);
  s.vertex(width/2-b, height/2-a/2);
  s.endShape(CLOSE);
}

void draw() {

 // ----------------Draw Cube-------------- 
  shape(s);  //Cube Outline

  
//------------------Centre Base Circles --------------
  drawCircle(width/2,height/2, c);
  drawCircle(width/2,height/2-c, c);
  drawCircle(width/2,height/2+c, c);
  drawCircle(width/2+f,height/2-g, c);
  drawCircle(width/2+f,height/2+g, c);
  drawCircle(width/2-f,height/2-g, c);
  drawCircle(width/2-f,height/2+g, c);
}

void drawCircle(float x, float y, float radius) {
  stroke(0);
  noFill();
  ellipse(x, y, radius, radius);
  if(radius > 20) {
    drawCircle(x, y, radius/4); 
    drawCircle(x, y + radius/4, radius/4);
    drawCircle(x, y - radius/4, radius/4);
    drawCircle(x + radius/4 * cos(radians(30)), y - radius/4 * cos(radians(60)), radius/4);
    drawCircle(x + radius/4 * cos(radians(30)), y + radius/4 * cos(radians(60)), radius/4);
    drawCircle(x - radius/4 * cos(radians(30)), y - radius/4 * cos(radians(60)), radius/4);
    drawCircle(x - radius/4 * cos(radians(30)), y + radius/4 * cos(radians(60)), radius/4);  
    drawCircle(x, y + radius/2, radius/4);
    drawCircle(x, y - radius/2, radius/4);
    drawCircle(x + radius/2 * cos(radians(30)), y - radius/2 * cos(radians(60)), radius/4);
    drawCircle(x + radius/2 * cos(radians(30)), y + radius/2 * cos(radians(60)), radius/4);
    drawCircle(x - radius/2 * cos(radians(30)), y - radius/2 * cos(radians(60)), radius/4);
    drawCircle(x - radius/2 * cos(radians(30)), y + radius/2 * cos(radians(60)), radius/4);
    }
}
1 Like

Maybe like this ?
Tell me if it is too complicated :wink:

PShape s; // The PShape object - Cube
int a = 500; // Declare variable - Radious Cube
float b = a * sqrt(3) / 2; // Height of triangle
float c = a * 2 / 3; // Circle02 Radious - 7Days of Creation

float f = c * cos(radians(30));
float g = c * cos(radians(60));

int nb = 0;
int maxVal = 5000;
ArrayList<Circle> array;
int index = 0;
int time = 0;
int timeValue = 1;

void setup() {
  fullScreen();
  background(255);
  stroke(0);
  strokeWeight(1);
  //frameRate(50);

  s = createShape(); //Cube Outline
  s.beginShape();
  s.noFill();
  s.stroke(0);
  s.vertex(width/2, height/2-a);
  s.vertex(width/2+b, height/2-a/2);
  s.vertex(width/2+b, height/2+a/2);
  s.vertex(width/2, height/2+a);
  s.vertex(width/2-b, height/2+a/2);
  s.vertex(width/2-b, height/2-a/2);
  s.endShape(CLOSE);
  
  array = new ArrayList<Circle>();
}

void draw() {
  
  if (nb<maxVal){
    // ----------------Draw Cube--------------
    shape(s); //Cube Outline
  
    //------------------Centre Base Circles --------------
    drawCircle(width/2, height/2, c);
    drawCircle(width/2, height/2-c, c);
    drawCircle(width/2, height/2+c, c);
    drawCircle(width/2+f, height/2-g, c);
    drawCircle(width/2+f, height/2+g, c);
    drawCircle(width/2-f, height/2-g, c);
    drawCircle(width/2-f, height/2+g, c);
  }else{
    
    if (millis()-time > timeValue && index<array.size()){
      array.get(index).display();
      time = millis();
      index++;
    }
  }
}

void drawCircle(float x, float y, float radius) {
  if (nb < maxVal){
    nb++;
    
    array.add(new Circle(x,y,radius));
    
    if (radius > 20) {
      drawCircle(x, y, radius/4);
      drawCircle(x, y + radius/4, radius/4);
      drawCircle(x, y - radius/4, radius/4);
      drawCircle(x + radius/4 * cos(radians(30)), y - radius/4 * cos(radians(60)), radius/4);
      drawCircle(x + radius/4 * cos(radians(30)), y + radius/4 * cos(radians(60)), radius/4);
      drawCircle(x - radius/4 * cos(radians(30)), y - radius/4 * cos(radians(60)), radius/4);
      drawCircle(x - radius/4 * cos(radians(30)), y + radius/4 * cos(radians(60)), radius/4);
      drawCircle(x, y + radius/2, radius/4);
      drawCircle(x, y - radius/2, radius/4);
      drawCircle(x + radius/2 * cos(radians(30)), y - radius/2 * cos(radians(60)), radius/4);
      drawCircle(x + radius/2 * cos(radians(30)), y + radius/2 * cos(radians(60)), radius/4);
      drawCircle(x - radius/2 * cos(radians(30)), y - radius/2 * cos(radians(60)), radius/4);
      drawCircle(x - radius/2 * cos(radians(30)), y + radius/2 * cos(radians(60)), radius/4);
    }
  }else{
    return;
  }
}


class Circle{
  float x,y,radius;
  
  Circle(float xx,float yy,float rad){
    x = xx;
    y = yy;
    radius = rad;
  }
  
  void display(){
    stroke(0);
    noFill();
    ellipse(x, y, radius, radius);
  }
}

Explanation :

  • Create a Circle class which stores coordinates and radius of an ellipse and add a display function to draw it
  • Initialize an ArrayList which will store all you Circles
  • Do the recursion and each time you call the function DrawCircle, add a Circle in your ArrayList array
  • When you finished to store all your ellipses (for exemple 5000) start to draw them one by one in the draw function with a time interval (timeVal)
1 Like

@josephh Please don’t just provide full code solutions without an explanation. Instead, try to walk people through the process of solving their own problems. That’s much more helpful for people who aren’t sure how to proceed!

@rolando One thing you might consider is adding int maxLevel and int currentLevel arguments to your drawCircle. Only make recursive calls to drawCircle() if currentLevel is less than maxLevel. That might sound confusing, but it generally looks like this:

int currentMaxLevel = 1;

void draw(){
  drawCircle(0, currentMaxLevel);
}

void drawCircle(int currentLevel, int maxLevel){
  //draw your circle

  if(currentLevel < maxLevel){
    drawCircle(currentLevel + 1, maxLevel);
  }
}

Then you can increase the currentMaxLevel over time to draw more levels of recursion.

If you’re still confused, please try to narrow your problem down to a MCVE instead of posting your whole program.

2 Likes

You are absolutly right I’m sorry.

Thank you both!

@josephh Its very close to what I am looking for! Thank you and even without an explicit explanation I was able to interrogate and learn through your answer. Im currently delving into ArrayLists and I am hoping to get the logic of your code.

@Kevin Would you care to elaborate a little more on how these proposed arguments (currentLevel and maxLevel) interact with my existing drawCircle variables? The way I set it up, the function drawCircle calls for the center and the diameter of the circle, if I replace them, where do I control the geometry from?

@rolando

ArrayLists aren’t complicated at all, check :

The code in my answer is just a partial example. The level variables wouldn’t replace your position or diameter variables- they would all be included.

There are a bunch of different ways to approach this though.