Mark9135
Mark9135

Reputation: 131

Processing PVector rotations

The issue is i got an array of PVectors placed around my main PVector which is in the middle. I want my array of PVectors to rotate around my main PVector based on a rotation variable. Is there any way to do this?

Right now I have this code but it does not rotate the PVectors, just places them farther away based on the rotation var.

class Box {
  PVector location;
  PVector[] points;
  float rotation = random(360);
  Box() {
    location = new PVector(random(width), random(height));
    points = new PVector[4];

    for(a = 0; a < points.length; a ++) {
      points[a] = new PVector(0,0); 
    }
  }

  void update() {
    points[0].x = location.x + 10 * sin(rotation);
    points[0].y = location.y + 10 * sin(rotation);

    points[1].x = location.x + 10 * sin(rotation);
    points[1].y = location.y - 10 * sin(rotation);

    points[2].x = location.x - 10 * sin(rotation);
    points[2].y = location.y + 10 * sin(rotation);

    points[3].x = location.x - 10 * sin(rotation);
    points[3].y = location.y - 10 * sin(rotation);
}

Upvotes: 0

Views: 1449

Answers (2)

Basilevs
Basilevs

Reputation: 23959

To rotate a point around location:

double x = cos(rotation) * (point.x-location.x) - sin(rotation) * (point.y-location.y) + location.x;
double y = sin(rotation) * (point.x-location.x) + cos(rotation) * (point.y-location.y) + location.y;
point.x = x;
point.y = y;

See Rotate a point by an angle

Upvotes: 0

kevinsa5
kevinsa5

Reputation: 3411

To rotate the vectors, you do need to use trig functions like sin and cos like you have in your code. However, your approach isn't really the best. Adding onto the existing (x,y) coordinates on each update isn't really feasible, since the number you have to add on is changing every time. It's easier just to overwrite and calculate new values for each update. The x and y coordinates for a given angle are given by the unit circle:

Unit Circle

So, the x of a given PVector varies with cos(theta) and the y varies with sin(theta). Check the following code:

Box b;

void setup(){
  size(300,300);
  b = new Box();
}
void draw(){
  background(255);
  b.update(mouseX, mouseY);
  b.display();
}

class Box {
  PVector location;
  PVector[] points;
  float rotation;
  float radius;
  Box() {
    location = new PVector(width/2,height/2);
    points = new PVector[7];
    rotation = 0;
    radius = 50;
    for(int i = 0; i < points.length; i ++) {
      //this centers the points around (0,0), so you need to add in
      //the box coordinates later on.
      points[i] = new PVector(radius*cos(rotation + i*TWO_PI/points.length),
                              radius*sin(rotation + i*TWO_PI/points.length)); 
    }
  }
  void update(int x, int y) {
    location.set(x,y);
    rotation += 0.08; // change for different rotation speeds.
    for(int i = 0; i < points.length; i++){
      points[i].set(radius*cos(rotation + i*TWO_PI/points.length),
                    radius*sin(rotation + i*TWO_PI/points.length)); 
    }
  }
  void display(){
    stroke(0);
    for(int i = 0; i < points.length; i++){
      //points are treated as offsets from the center point:
      line(location.x,location.y,location.x+points[i].x,location.y+points[i].y);
      ellipse(location.x+points[i].x,location.y+points[i].y,10,10);
    }
  }
}

For every update() call, it increments the rotation variable and calculates the new x and y values for each point in the array. You can change the speed and direction of rotation by changing 0.08 to bigger/smaller/positive/negative numbers.

Upvotes: 1

Related Questions