Spiral with connecting lines between adjacent points

Hi,
I’m a newbie on here. I was wondering if I could get some help, please. I’ve been set a task of drawing a spiral made up from squares with lines connecting adjacent points and stuck on how to approach it.
Heres what its meant to look like.
spin

Here’s my code for the spiral:

//Sets up the canvas
void setup() {
  size (800, 800);
  background(255);
}

//Draws what ever is in the function.
void draw() {

  for (int i = 0; i < 108; i++) {
    float angle = radians(i);
    float xcent= width/2; //Center of circle on x axis
    float ycent = height/2; //Center of circle on y axis.

    //Sine and Consine is used to find the center of the circle which is being drawn.
    float radius = 250 - i;
    float xcord = xcent + cos(angle*10) * radius;  
    float ycord = ycent + sin(angle*10) * radius;
    float px = xcent + cos(angle*10) * radius;
    float py = ycent + sin(angle*10) * radius;

    //Loop that draws the squares and fills them with the specific colour.

    fill(255, 0, 0);
    if (i >72) {
      fill(0, 0, 255);
    } else if (i  >36) {
      fill(0, 255, 0);
    }
    rect(xcord, ycord, 10, 10);
    
    line(xcord, ycord, px, radius);


  }
}

1 Like

Hi oscie24,

Before helping you, I just wanna point out that you don’t need to have a draw function for what you want to do. All your code can go in the setup() function like so:

//Sets up the canvas
void setup() {
  size (800, 800);
  background(255);
  
  for (int i = 0; i < 108; i++) {
    float angle = radians(i);
    float xcent= width/2; //Center of circle on x axis
    float ycent = height/2; //Center of circle on y axis.

    //Sine and Consine is used to find the center of the circle which is being drawn.
    float radius = 250 - i;
    float xcord = xcent + cos(angle*10) * radius;  
    float ycord = ycent + sin(angle*10) * radius;
    float px = xcent + cos(angle*10) * radius;
    float py = ycent + sin(angle*10) * radius;

    //Loop that draws the squares and fills them with the specific colour.

    fill(255, 0, 0);
    if (i >72) {
      fill(0, 0, 255);
    } else if (i  >36) {
      fill(0, 255, 0);
    }
    rect(xcord, ycord, 10, 10);
    
    line(xcord, ycord, px, py);
  }
}

Draw is called 60 times per second so your are drawing your squares over and over 60 times per second.

Now for your question, you need a way in your for loop to remember the previous point you draw. To do that you can simply create 2 variables previousX and previousY and at the end of a loop you store the x and y coordinate of the point you just drew. This way during the next loop, you can draw a line from the previous point to the new one.

1 Like

Could you show me how that’s done?? I’m just having a moment and I cant think how to do it.

Start by adding two new variables that will remember the position of the previous square you drew. What type of variables will they be? What will their names be? Bonus question: What would be a good initial value for these new variables?

Now change the line of code that draws your line. Which line of code is it? Hint: It’s drawing a line(). Change the parameters to the line() function so that it draws the line between the current square’s position (which variables are the current position?) and the previous square’s position (which variables are those? Hint: You just added them!).

Now that you’ve draw the current square, you have to remember that it will be the previous square for the next square. So record its position in the previous square’s position variables.

This will work, and you will get lines drawn between your squares - but there will be issues! We realize this, but are reluctant to help you further (or provide a full-code solution) until you have demonstrated some of your own effort into changing the code you have.

2 Likes

I have made another attempt, the problem I have now is that the line i drew isn’t appearing.

//Sets up the canvas
void setup() {
  size (800, 800);
  background(255);
}

//Draws what ever is in the function.
void draw() {

  for (int i = 0; i < 108; i++) {
    float angle = radians(i);
    float xcent= width/2; //Center of circle on x axis
    float ycent = height/2; //Center of circle on y axis.

    //Sine and Consine is used to find the center of the circle which is being drawn.
    float radius = 250 - i;
    float xcord = xcent + cos(angle*10) * radius;  
    float ycord = ycent + sin(angle*10) * radius;
    float px = xcent + cos(angle*10) * radius;  
    float py = ycent + sin(angle*10) * radius;




    //Loop that draws the squares and fills them with the specific colour.

    fill(255, 0, 0);

    if (i >72) {
      fill(0, 0, 255);
    } else if (i  >36) {
      fill(0, 255, 0);
    }
    rect(xcord, ycord, 10, 10);

  px = xcord;
  py = ycord;
    
   line(xcord,ycord,px,py);
  }
}

1 Like

Okay. Since you want the previous position from one iteration of your loop to be available in the next iteration, you can’t define the variables that save the previous position inside the loop! (You could, however, calculate what the previous position was, but this would be a duplication of effort.) That means that you need to declare them before the loop starts.

void draw(){
 // ...
 float previous_square_position_X;
 float previous_square_position_Y;
 for( ... ){
  // draw square (px, py)
  // draw a line (px, py, previous_square_position_X, previous_square_position_Y)
  // save current position for use in next iteration
  previous_square_position_X = px;
  previous_square_position_Y = py;
}
}

Getting close. Give it another try.

1 Like

I will give it another try. I better understanding now that you have explained it that way. I was just given the task with no guidance. Thanks

Thats what I have done, but don’t know whats missing.

void draw() {

  float previous_square_position_X;
  float previous_square_position_Y;


  for (int i = 0; i < 108; i++) {

    float p_radius = 250-i;
    float p_xcent = width/2;
    float p_ycent = height/2;
    float p_angle = radians(i);
    float px = p_xcent + cos(p_angle*10) * p_radius;  
    float py = p_ycent + sin(p_angle*10) * p_radius;
    

    rect(px, py, 10, 10);
    previous_square_position_X = px;
    previous_square_position_Y = py;
    line(px, py, previous_square_position_X, previous_square_position_Y);

     
  }

You are assigning the new values to the previous variables before drawing your line so you are drawing a line from the new point to the new point.

Just change the position of the line() function and it should works

I tried that but don’t know where. Getting errors when I try to move it.

jb4x literally just told you exactly what is wrong. You are changing the “previous position” variables to have the current position before you are drawing the line.

You need to change them AFTER you have drawn the line.

Wrong:

prevX = currX;
prevY = currY;
line( currX, currY, prevX, prevY );

Right:

line( currX, currY, prevX, prevY );
prevX = currX;
prevY = currY;

That you couldn’t fix this after having being told exactly what is wrong with it is EXTREMELY troubling. Please take some time to understand your own code… and how variable assignment works. Please. Please please please.

I did that but in then says the previous_square_position X and Y aren’t initialised so i was confused.

This is giving me errors.

float previous_square_position_X;
  float previous_square_position_Y;


  for (int i = 0; i < 108; i++) {

    float p_radius = 250-i;
    float p_xcent = width/2;
    float p_ycent = height/2;
    float p_angle = radians(i);
    float px = p_xcent + cos(p_angle*10) * p_radius;  
    float py = p_ycent + sin(p_angle*10) * p_radius;
    

   rect(px, py, 10, 10);
   line(px, py, previous_square_position_X, previous_square_position_Y);
    previous_square_position_X = px;
    previous_square_position_Y = py;
    
        
  }

You still need to figure out the original stage of your variables.

The first time you enter your for loop, previous_square_position_X and previous_square_position_Y are not defined yet.

A way to solve that is to initialize your previous variable with the value you have when i = 0 and start the for loop at i = 1.

Thanks, that really helped. the only problem now is that it looks like this:

and the code is this:

void draw() {

  float previous_square_position_X = 0;  
  float previous_square_position_Y = 0; 


  for (int i = 0; i < 108; i++) {

    float p_radius = 250-i;
    float p_xcent = width/2;
    float p_ycent = height/2;
    float p_angle = radians(i);
    float px = p_xcent + cos(p_angle*10) * p_radius;  
    float py = p_ycent + sin(p_angle*10) * p_radius;
  
   

   rect(px, py, 10, 10);
   line(px, py, previous_square_position_X, previous_square_position_Y);
    
    previous_square_position_X = px;
    previous_square_position_Y = py;
        
  }

Carefully read my post again, your initialization is wrong here. The first point should not be (0, 0).

Good enough for me.

float cx, cy, a, r, px=-1, py=-1;

void setup() {
  size(800, 800);
}

void draw() {
  background(255);
  translate(width/2, height/2);
  for (int t = 0; t < 2; t++) {
    for (int i = 0; i < 108; i++) {
      a = 10*radians(i);
      r = 250 - i;
      cx = r*cos(a);
      cy = r*sin(a);
      fill(255, 0, 0);
      if (i >= 72) {
        fill(0, 0, 255);
      } else if (i >= 36) {
        fill(0, 255, 0);
      }
      if ( t == 0 ) {
        if ( px != -1 ) {
          line(cx+5, cy+5, px, py);
        }
        px = cx+5;
        py = cy+5;
      } else {
        rect(cx, cy, 10, 10);
      }
    }
  }
  noLoop();
}
1 Like

A post was merged into an existing topic: Arrays to draw lines

So start - or return to - your own thread. This discussion has sort of ended, given that the spiral now has lines drawn between the squares.