Draw a trail of rectangles recursive

I want to draw a trail of rectangles with the latest in the list being in the center of the window. I do this recursively, but I don’t get exactly what I’m doing wrong, since only 2 rectangles are drawn and not 100 (max list size)

import java.util.List;
import java.util.ArrayList;

float xCoord;
float yCoord;
float oldxCoord;
float oldyCoord;
float rectSizeX = 20;
float rectSizeY = 20;
List<deltaXY> coordinates;

void setup() {
  background(0);
  size(400,400);
  xCoord = 0.0 ;
  yCoord = 0.0;
  coordinates = new ArrayList<deltaXY>();
}

void draw(){
  fill(#FFFFFF, 10);
    noStroke();
    rectMode(CENTER);
    //rect(0.5 * width, 0.5 * height, rectSizeX, rectSizeY);
    oldxCoord = xCoord;
    oldyCoord = yCoord;
    xCoord +=10;
    yCoord += 10;
    deltaXY dXY = new deltaXY();
    coordinates.add(dXY);
    if(coordinates.size() >=100) {
      coordinates.remove(0);
    }
    r(coordinates.size()-1);
    

}

void r(int i){
  float x = 0.5* width;
    float y = 0.5* height;
    float traceX = 0;
    float traceY = 0;
    if (i==0) {
      fill(#FFFFFF, 10);
    noStroke();
    rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);
      
    }
    else {
      float dx = coordinates.get(i).dx;
      float dy = coordinates.get(i).dy;
      traceX += dx;
      traceY += dy;
      fill(#FFFFFF, 10);
      noStroke();
      rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);      
      r(i-1);
    }
    
}

class deltaXY {
  float dx;
  float dy;
  
  deltaXY() {
    dx = xCoord-oldxCoord;
    dy = yCoord - oldyCoord;
    
  }
  
}
1 Like

For starters…

  1. I moved traceX and traceY outside of method.
    https://processing.org/examples/variablescope.html
  2. Changed colors (red and green) so I could see them in plot.

I did not examine code further.

float traceX = 0;
float traceY = 0;

void r(int i)
  {
  float x = 0.5* width;
    float y = 0.5* height;
    //float traceX = 0;
    //float traceY = 0;
    if (i==0) 
      {
      fill(255, 0, 0, 100);
      noStroke();
      rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);
      }
    else 
      {
      float dx = coordinates.get(i).dx;
      float dy = coordinates.get(i).dy;
      traceX += dx;
      traceY += dy;
      fill(0, 255, 0, 100);
      noStroke();
      rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);      
      r(i-1);
      }
    }
2 Likes

Thanks! I changed it.

Now it appears that the new values for dx and dy that I put in the list stay the same.

println(dXY.getDX() , dXY.getDY()); always gives “10.0, 10.0” while I want it (as it should get in the ArrayList ) 10.0 next time 20.0 etc.

import java.util.List;
import java.util.ArrayList;

float xCoord ;
float yCoord ;
float oldxCoord;
float oldyCoord;
float rectSizeX = 20;
float rectSizeY = 20;
List<deltaXY> coordinates;
float x ;
float y ;
float traceX = 0;
float traceY = 0;
deltaXY dXY;

void setup() {
  background(0);
  size(400,400);
  xCoord = 0.0 ;
  yCoord = 0.0;
  coordinates = new ArrayList<deltaXY>();
  x = 0.5* width;
  y = 0.5* height;
  dXY = new deltaXY();
}

void draw(){
  fill(#FFFFFF, 10);
    noStroke();
    rectMode(CENTER);
    //rect(0.5 * width, 0.5 * height, rectSizeX, rectSizeY);
    oldxCoord = xCoord;
    oldyCoord = yCoord;
    xCoord = xCoord + 10;
    yCoord = yCoord + 10;
    println(xCoord, oldxCoord);
    dXY.setDX(xCoord, oldxCoord);
    dXY.setDY(yCoord, oldyCoord);
    
    println(dXY.getDX() , dXY.getDY());

    coordinates.add(dXY);
    if(coordinates.size() >=100) {
      coordinates.remove(0);
    }
    r(coordinates.size()-1);


}

void r(int i){

    if (i==0) {
      fill(#FFFFFF, 10);
      noStroke();
      rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);      
    }
    else {
      float dx = coordinates.get(i).getDX();
      float dy = coordinates.get(i).getDY();
      traceX += dx;
      traceY += dy;
      fill(#FFFFFF, 10);
      noStroke();
      rectMode(CENTER);
      rect(x+traceX, y+traceY, rectSizeX, rectSizeY);      
      r(i-1);
    }
    
}

class deltaXY {
  float dx;
  float dy;
  
  deltaXY() {    
  }
  
  public void setDX(float xCoord, float oldxCoord) {
    this.dx = xCoord-oldxCoord;
  }
  
  public void setDY(float yCoord, float oldyCoord) {
    this.dy = yCoord-oldyCoord;
  }
  
  public float getDX() {
    return this.dx; 
  }
  
  public float getDY() {
     return this.dy; 
  }
}

Hey there!

My first suggestion is to move size() to the top of setup:

In a program that has the setup() function, the size() function must be the first line of code inside setup()
source

About your issue: I don’t think there are only two rectangles drawn, but instead they’re being drawn on top of each other. It’s hard to see however because the stage isn’t being reset and the framerate is too high. Try to refresh the background and greatly reduce the framerate, and you’ll likely get a better understanding of what’s happening :slight_smile:

You are right. When I print the X and Y coordinates (as posted in my earlier post) it prints the same coordinates over and over. The problem is thus not in the recursion (so far) but in storing the list of coordinates (now it is 10.0 over and over, and it should start witch 0, 10, and increase by 10 each time

In your updated code the rectangles actually seem to be moving, but again quite fast (and very transparent). Have you noticed that? If not, try to the code below (click mouse to jump to the next frame):

import java.util.List;
import java.util.ArrayList;

float xCoord, yCoord, oldxCoord, oldyCoord;
float rectSizeX = 20;
float rectSizeY = 20;
List<deltaXY> coordinates;
float x, y, traceX, traceY;
deltaXY dXY;

void setup() {
  size(400, 400);
  background(0);
  coordinates = new ArrayList<deltaXY>();
  x = 0.5 * width;
  y = 0.5 * height;
  dXY = new deltaXY();
  noLoop();
}

void draw() {
  fill(#FFFFFF, 10);
  noStroke();
  rectMode(CENTER);
  //rect(0.5 * width, 0.5 * height, rectSizeX, rectSizeY);
  oldxCoord = xCoord;
  oldyCoord = yCoord;
  xCoord = xCoord + 10;
  yCoord = yCoord + 10;
  println(xCoord, oldxCoord);
  dXY.setDX(xCoord, oldxCoord);
  dXY.setDY(yCoord, oldyCoord);

  println(dXY.getDX(), dXY.getDY());

  coordinates.add(dXY);
  if (coordinates.size() >=100) {
    coordinates.remove(0);
  }
  r(coordinates.size()-1);
}

void r(int i) {
  if (i==0) {
    fill(#FFFFFF, 10);
    noStroke();
    rectMode(CENTER);
    rect(x+traceX, y+traceY, rectSizeX, rectSizeY);
  } else {
    float dx = coordinates.get(i).getDX();
    float dy = coordinates.get(i).getDY();
    traceX += dx;
    traceY += dy;
    fill(#FFFFFF, 50);
    noStroke();
    rectMode(CENTER);
    rect(x+traceX, y+traceY, rectSizeX, rectSizeY);      
    r(i-1);
  }
}

class deltaXY {
  float dx;
  float dy;

  deltaXY() {
  }

  public void setDX(float xCoord, float oldxCoord) {
    this.dx = xCoord-oldxCoord;
  }  
  public void setDY(float yCoord, float oldyCoord) {
    this.dy = yCoord-oldyCoord;
  }  
  public float getDX() {
    return this.dx;
  }  
  public float getDY() {
    return this.dy;
  }
}

void mousePressed() {
  redraw();
  println("frame # = " + frameCount);
}
1 Like

the noLoop()-mousePressed()-redraw() is a particularly great way to understand complicated state changes, those that have a noticeable effect from frame to frame.

But this approach doesn’t work when the difference between the frames - each trip through draw() - is slight, like it will be in a trail of rects. Too hard to correlate each mouseClick with incremental change because you’re iterating with low alpha fill values.

Do: frameRate(2) at the end of your setup() block. This will slow things waaayy down and let you understand your program’s operation.

Try to remember that your code is telling a story, but its in a different language, and so it requires a translation narrative. You must express your code’s intentions. Actually try to relate your function names with what they do, instead of just r(i), which imparts zero information to anyone trying to read your code.

Keep it up!

1 Like