Search code examples
javaprocessingpolar-coordinatesspiral

Move along spiral to the centre with cartasian coordinates given at the start


I would like to move the ellipse along the spiral to the centre of the screen - the starting point of the ellipse is given via x and y coordinates. Well I have no idea how to push the spiral inward the centre (I can achieve this by adding width/2 and height/2 to the x,y) AND AT THE SAME TIME start the movement at the given cartasian (x,y) coordinates. Below is the code. Help appreciated! I have been trying to do this in processing (java):

float r = 0; //radius
float x = 700; // x of the object
float y = 50; // y of the object
float theta = 0; //angle

void setup() {
  size(800,600);
  background(0);
  smooth();

  r = sqrt(x*x+y*y); //polar coordinate - distance from x,y to 0,0 on the grid
  theta = atan(y/x); // angle to 0,0 on the grid

}

void draw() {

  fill(0,255,0);
  rect(width/2,height/2,20,20);

  fill(0,0,255);
  rect(700,50,20,20);

  float x = r * cos(theta);
  float y = r * sin(theta);

  // Draw an ellipse at x,y
  noStroke();
  fill(255,0,0);

  ellipse(x, y, 16, 16); 

  if (r>0){
  r -= 1; // Increment the radius
  theta += 0.01; // Increment the angle
  }
}

Solution

  • You could translate your x,y and then translate the draw loop.

    This makes it so that you're working with a coordinate system with 0,0 at the center of the screen instead of at the top-left of the screen.

    Your distance and angle formulas are using 0,0 as the origin, which is not the center of the screen if you use a top-left origin system (like Processing). You could also modify those formulas instead.

    The below code is an edit of yours to make 0,0 at the center of your screen.

    float r = 0; //radius
    float x = 100; // x of the object
    float y = 100; // y of the object
    float theta = 0; //angle
    
    void setup() {
      size(800,600);
      background(0);
      smooth();
      ellipseMode(CENTER); // draw ellipses based on their center
    
      // translate the x and y from top-left origin to center origin 
      x -= width/2;
      y -= height/2;
    
      r = sqrt(x*x+y*y); //polar coordinate - distance from x,y to 0,0 on the grid
      theta = atan(y/x); // angle to 0,0 on the grid
    
    }
    
    void draw() {
      translate(width/2, height/2); // translate the whole canvas
    
      fill(0,255,0);
      ellipse(0,0,20,20); // mark the center of the canvas
    
      fill(0,0,255);
      ellipse(x,y,20,20); // mark the start point for the circle
    
      // flip the angle if left of the origin
      int flip = 1;
      if(x < 0) flip = -1;
    
      float x = r * cos(theta) * flip;
      float y = r * sin(theta) * flip;
    
      // Draw an ellipse at x,y
      noStroke();
      fill(255,0,0);
    
      ellipse(x, y, 16, 16); 
    
      if (r>0){
      r -= 1; // Decrement the radius
      theta += 0.01; // Increment the angle
      }
    
    }
    

    The below code keeps the top-left origin, but modifies the initialization of the radius and angle to be relative to the center of the screen.

    float x = 100; // x of the object
    float y = 100; // y of the object
    float r = 0; // radius
    float theta = 0; // angle
    
    void setup() {
      size(800,600);
      background(0);
      smooth();
      ellipseMode(CENTER); // draw ellipses based on their center
    
      // distance between point and center of screen
      r = dist(x,y,width/2,height/2);
    
      // http://stackoverflow.com/a/7586218/1736092
      // angle of line between point and center of screen 
      // relative to x-axis
      float dX = x - width/2;
      float dY = y - height/2; 
      theta = atan2(dY, dX);
    
      stroke(0, 255, 0); // green stroke
      line(x, y, width/2, height/2); // draw radius
    
      noStroke();
      fill(0, 255, 0);  // green fill
      ellipse(width/2, height/2, 20, 20); // mark the center of the canvas
      fill(0, 0, 255); // blue fill
      ellipse(x, y, 20, 20); // mark the start point for the circle
    }
    
    void draw() {
      float x = r * cos(theta) + width/2;
      float y = r * sin(theta) + height/2;
    
      noStroke();
      fill(255,0,0); // red fill
      ellipse(x, y, 16, 16); 
    
      if(r>0) {
        r -= 1; // Decrement the radius
        theta += 0.01; // Increment the angle
      }
    }