# Trigonometry instead of rotate()

**URL:** <https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848>\
**Category:** Coding Questions\
**Created:** [January 25, 2019, 11:52pm UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848 "2019-01-25T23:52:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ov3rM1nD](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ov3rm1nd/32/1756_2.png) [@Ov3rM1nD](https://discourse.processing.org/u/Ov3rM1nD)\
**Post date:** [January 25, 2019, 11:52pm UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848/1 "2019-01-25T23:52:58Z")

</div>

Hello everybody. I’m making my own Triangle class that builds triangle objects with some unique features like collision detection, rotate (), centerMode () (which can be VERTEX, CENTROID, CIRCUNCENTER, etc), and a few other things I need.  
My problem is that I cannot update the values ​​of the vertices whenever I call my own rotate () method. I’m using an array of PVector to store the coordinates of the three vertices of the triangle (I need this to calculate collision adetection), so I cannot just use the Processing’s own rotate() method, because it doesn’t affect the coordinates values, only the rendering. Instead, I’m using trigonometry to calculate the rotation.  
I broke down my code so you can analyse the problem:

```auto
PVector[] p = new PVector[3];
float centerX, centerY;

void setup() {
  size(300, 300);
  centerX = width/2;
  centerY = height/2;

 // Let's create a equilateral triangle with polar coordinates
  for (int i = 0; i < p.length; i++) {
    float x = 100 * cos(i * 2*THIRD_PI) + centerX;
    float y = 100 * sin(i * 2*THIRD_PI) + centerY;
    p[i] = new PVector(x, y);
  }
}

void draw() {
  background(-1);
  line(0, height/2, width, height/2);
  line(width/2, 0, width/2, height);

  final float inc = frameCount * 0.01; // rotation increment 

  translate(centerX, centerY);
  for (int i = 0; i < p.length; i++) {
    float r = dist(centerX, centerY, p[i].x, p[i].y); // calculate each radius
    float ang = atan2(p[i].x, p[i].y); // calculates the angle between each point and the origin
    
    // we must add PI to offset the angle back to its original amplitude
    float x = r * cos(PI + ang + inc); 
    float y = r * sin(PI + ang + inc);

    fill(#FF0000);
    ellipse(x, y, 10, 10);
  }
}

```

What am i doing wrong? Am i missing something? Here’s a even smaller version with only one PVector point. It works just fine:

```auto
PVector p;
float centerX, centerY;

void setup() {
  size(300, 300);
  centerX = width/2;
  centerY = height/2;
  p = new PVector(50, 50);
}

void draw() {
  background(-1);
  
  final float inc = frameCount * 0.01;

  translate(centerX, centerY);
  float r = dist(centerX, centerY, p.x, p.y);
  float ang = atan2(p.x, p.y);

  float x = r * cos(PI + ang + inc);
  float y = r * sin(PI + ang + inc);

  fill(#FF0000);
  ellipse(x, y, 10, 10);
}

```

In short, I want to be able to rotate every vertex of the triangle without using Processing’s rotate() method. Thank you in advance 🤗

---

<div class="post-metadata">

**Author:** ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)\
**Post date:** [January 26, 2019, 8:34am UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848/2 "2019-01-26T08:34:25Z")

</div>

Atan2 uses y then x. Not sure if there anything else in your code, just something I noticed off the top.

---

<div class="post-metadata">

**Author:** ![Ov3rM1nD](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ov3rm1nd/32/1756_2.png) [@Ov3rM1nD](https://discourse.processing.org/u/Ov3rM1nD)\
**Post date:** [January 26, 2019, 7:32pm UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848/3 "2019-01-26T19:32:18Z")

</div>

Yeah I know the reference say we must use y first then x, but that’s not the problem here 🤔 I have tried it before as well… if you copy and try the code yourself you’ll see that I actually need to put x before y.

---

<div class="post-metadata">

**Author:** ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)\
**Post date:** [January 26, 2019, 8:23pm UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848/4 "2019-01-26T20:23:50Z")

</div>

Sorry, was on the phone and could not run it. try this:  
Replace

```auto
   // we must add PI to offset the angle back to its original amplitude
    float x = r * cos(PI + ang + inc); 
    float y = r * sin(PI + ang + inc);

```

with

```auto
// we must add PI to offset the angle back to its original amplitude
    float x = r * cos(i * 2*THIRD_PI + ang + inc); 
    float y = r * sin(i * 2*THIRD_PI + ang + inc);

```

This works on my end as far as 3 red dots forming a triangle rotating around point 0,0. Not sure if this answers your question, will grab some snippets of my rotate functions and post them in a few.

---

<div class="post-metadata">

**Author:** ![William3954](https://avatars.discourse-cdn.com/v4/letter/w/6a8cbe/32.png) [@William3954](https://discourse.processing.org/u/William3954)\
**Post date:** [January 26, 2019, 8:31pm UTC](https://discourse.processing.org/t/trigonometry-instead-of-rotate/7848/5 "2019-01-26T20:31:23Z")

</div>

Some functions/snippets I use for rotations. Not really optimized but they work for me. If you have any suggestions on to improve them, please let me know.

```auto
//Rotates a PVector around a centerpoint in degrees. Returns PVector
PVector RotPV(PVector inPVc, PVector inPVr, float degree) {
  float radian = radians(degree);
  PVector PVr = new PVector(inPVc.x + cos(radian) * (inPVr.x - inPVc.x) - sin(radian) * (inPVr.y - inPVc.y), inPVc.y + sin(radian) * (inPVr.x - inPVc.x) + cos(radian) * (inPVr.y - inPVc.y));
  return PVr;
}

```

```auto
PVector PolarToCart(PVector CenterPointIn, float degreesIn, float radiusIn ) {
  float tx2 = radiusIn*cos(radians(degreesIn));
  float ty2 = radiusIn*sin(radians(degreesIn));
  tx2=tx2+CenterPointIn.x;
  ty2=ty2+CenterPointIn.y;
  return new PVector(tx2, ty2);
}

```

```auto
// Any angle in the >= -TWO_PI will be fixed to give the 
// same angle in the range >=0 and < TWO_PI
float fixAngle(float angle) {
  return (angle + TWO_PI)%TWO_PI;
}

```

```auto
PVector ReturnPointonArc(PVector ArcCenter, float radius, float degree) {   
  float xP = ArcCenter.x + (cos(radians(degree)) * radius);
  float yP = ArcCenter.y + (sin(radians(degree)) * radius);
  return new PVector(xP, yP);
}

```

```auto
// Center point is p1; angle returned in degrees
float findAngle(PVector p0, PVector p1, PVector p2) {
  float a = pow(p1.x-p0.x, 2) + pow(p1.y-p0.y, 2);
  float b = pow(p1.x-p2.x, 2) + pow(p1.y-p2.y, 2);
  float c = pow(p2.x-p0.x, 2) + pow(p2.y-p0.y, 2);
  return degrees(acos( (a+b-c) / sqrt(4*a*b) ));
}

```

```auto
// Center point is p1; angle returned in degrees
float findAngle(PVector p0, PVector p1) {
  float a = atan2(p0.y-p1.y, p0.x-p1.x);
  return degrees(a);
}

```
