Help with rotation in simple animation

Hi! I’m relatively new to Processing, and I’ve been practicing with some simple visualizations. I feel that I’m 90% of the way there but can use some help to get the last step(s).

My goal is to draw a row of dots (Point objects in the code) that rotate around the origin. Each consecutive point should be connected by a line no matter where the points are as they move. It would look like something similar to: https://drive.google.com/file/d/1baLZbgr0A–VFXu2iLllyHXoYXk_jgjj/view?usp=sharing. Here is my full current code:

Point[] points;

void setup(){
  size(800,800);
  translate(width/2, height/2);
  background(0);
  colorMode(HSB,100);
  fill(100);
  stroke(100);
  strokeWeight(2);
  
  points = new Point[18];
  for(int i=0; i<points.length; i++){
    points[i] = new Point(i*20+20, 0, 0, 0.2);
  }
}

void draw(){
  background(0);
  translate(width/2, height/2);
  for(int i=0; i<points.length; i++){
    points[i].step();
    points[i].display();
    if(i!=0){
      line(points[i-1].x, points[i-1].y, points[i].x, points[i].y);
    }
  }
  return;
}

class Point{
  float x, y, theta, speed, screenX, screenY;
  Point(float xTemp, float yTemp, float thetaTemp, float speedTemp){
    x = xTemp;
    y = yTemp;
    theta = thetaTemp;
    speed = speedTemp;
    //screenX = screenX(x,y);
    //screenY = screenY(x,y);
  }
  
  void step(){
    rotate(-radians(theta));
    theta += speed;
  }
  
  void display(){
    ellipse(x, y, 8, 8);
  }
}

Right now I’m using a step function every draw cycle for each point object in the Point array in which I rotate the canvas. Each point has an x position that initially aligns the points on the x axis. Each point’s y value is 0 so that the rotate (step) function controls the points’ positions on the screen in a radial fashion. (I only included a y value for each point object so that the lines would have coordinates to draw to.)

The points draw exactly how I’d like, but the lines are not being drawn between dots correctly. You can see by running the code at the bottom of this post that there are small lines attached to the dots. They are drawn at the first frame (and are length i*20 as set by the instantiation line of code) but then just stay that length and move with their associated point. I suspect this problem might be due to the step function causing an issue with drawing between the “current” vs “last” iteration of the dots. However, since the lines don’t change length each frame, it could be that I’m missing or messing up instructions to update the position of one end of each line.

A got bit of success by excluding the draw() function altogether and using the following setup():

void setup(){
  size(800,800);
  translate(width/2, height/2);
  background(0);
  colorMode(HSB,100);
  fill(100);
  stroke(100);
  strokeWeight(2);
  
  points = new Point[18];
  for(int i=0; i<points.length; i++){
    points[i] = new Point(i*20+20, i*i, 0, 0.2);
    points[i].display();
    if(i!=0){
      line(points[i-1].x, points[i-1].y, points[i].x, points[i].y);
    }
  }
}

Notice that I used i*i for each point’s relative y position to emphasize that lines of appropriate lengths can be drawn successfully between each consecutive point. It results in this static image:


So I’m trying to figure out how to replicate this successful dot-connecting but in the animated draw function.

Another line of thought: because it looks like rotating the canvas for each point is making things complicated for drawing the lines, I’ve also experimented a bit with keeping the step function but using screenX() and screenY(), which I thought might just grab the x,y coordinates of the drawn points relative to the window rather than relative to the rotated canvas(es). The code for this test looks like: uncomment the screenX and screenY definitions in the class and then use line(points[i-1].screenX, points[i-1].screenY, points[i].x, points[i].y) in draw (or something like that). None of the combinations of x, y, screenX, and screenY that I’ve tried in this line work the way I want, but I feel like the concept of getting the points’ x,y coordinates on the screen rather than on their rotated coordinate systems might be onto something.

Any help would be appreciated! Thanks!

1 Like

Hi,

PVectors:
https://www.processing.org/tutorials/pvector/

A simple example I wrote a while back exploring PVectors:

PVector v1, v2, v3, v4, v5;

void settings()
  {
  size(500, 500, P2D);
  }
  
void draw()
  { 
  background(0);  
 pushMatrix();
  translate(width/2, 3*height/4);
  strokeWeight(5);
  stroke(255, 255, 0);  
  v1 = new PVector(50, 0);  
  v2 = new PVector(50, 0);
  v3 = new PVector(50, 0);  
  v4 = new PVector(50, 0); 
  v5 = new PVector(50, 0);

  float rotX = map(mouseX, 0, width, -PI, +0);
  v1.rotate(rotX);  
  line(0, 0, v1.x, v1.y);  

  float rotY = map(mouseY, 0, width, -PI/4, PI/4);
  v2.rotate(rotX);
  v2.rotate(1*rotY); 
  println(v2);
  v2 = PVector.add(v1, v2);
  println(v2);
  line(v1.x, v1.y, v2.x, v2.y);
  
  v3.rotate(rotX);
  v3.rotate(2*rotY); 
  v3 = PVector.add(v2, v3);
  line(v2.x, v2.y, v3.x, v3.y);  

  v4.rotate(rotX);
  v4.rotate(3*rotY); 
  v4 = PVector.add(v3, v4);
  line(v3.x, v3.y, v4.x, v4.y); 

  v5.rotate(rotX);
  v5.rotate(4*rotY); 
  v5 = PVector.add(v4, v5);
  line(v4.x, v4.y, v5.x, v5.y);   
  popMatrix();  
  }

:slight_smile:

1 Like

Thanks, glv for the response. While playing around with your suggestion, I figured out an alternative solution without using vectors. Here it is for the benefit of anyone in a similar situation.

The general logic was sound, except that I wasn’t updating the position of the point itself but rather only the coordinate system. I switched from a polar approach to a cartesian approach using px=cos(radians(theta))(x) and py=sin(radians(theta))(x). This way I achieved the same circular motion and also saved these positions to other variables (px and py) that would be updated in every step() call.

That solved my problem. Hope this helps the community!

Point[] points;

void setup(){
  size(800,800);
  translate(width/2, height/2);
  background(0);
  colorMode(HSB,100);
  fill(100);
  stroke(100);
  strokeWeight(2);
  
  points = new Point[18];
  for(int i=0; i<points.length; i++){
    points[i] = new Point(i*20, 0, i/3.0);
  }
}

void draw(){
  background(20);
  translate(width/2, height/2);
  for(int i=0; i<points.length; i++){
    points[i].step();
    points[i].display();
    if(i!=0){
      line(points[i-1].px, points[i-1].py, points[i].px, points[i].py);
    }
  }
  return;
}

class Point{
  float x, theta, speed, px, py;
  Point(float x_, float theta_, float speed_){
    x = x_;
    theta = theta_;
    speed = speed_;
  }
  
  void step(){
    px = cos(radians(theta))*(x);
    py = sin(radians(theta))*(x);
    theta += speed;
  }
  
  void display(){
    ellipse(px, py, 8, 8);
  }
}
4 Likes