2D Euclidean vector rotations

C++MathVectorRotationTrigonometry

C++ Problem Overview


I have a euclidean vector a sitting at the coordinates (0, 1). I want to rotate a by 90 degrees (clockwise) around the origin: (0, 0).

If I have a proper understanding of how this should work, the resultant (x, y) coordinates after the rotation should be (1, 0). If I were to rotate it by 45 degrees (still clockwise) instead, I would have expected the resultant coordinates to be (0.707, 0.707).

theta = deg2rad(angle);

cs = cos(theta);
sn = sin(theta);

x = x * cs - y * sn;
y = x * sn + y * cs;

Using the above code, with an angle value of 90.0 degrees, the resultant coordinates are: (-1, 1). And I am so damn confused. The examples seen in the following links represent the same formula shown above surely?

What have I done wrong? Or have I misunderstood how a vector is to be rotated?

C++ Solutions


Solution 1 - C++

Rotating a vector 90 degrees is particularily simple.

(x, y) rotated 90 degrees around (0, 0) is (-y, x).

If you want to rotate clockwise, you simply do it the other way around, getting (y, -x).

Solution 2 - C++

you should remove the vars from the function:

x = x * cs - y * sn; // now x is something different than original vector x
y = x * sn + y * cs;

create new coordinates becomes, to avoid calculation of x before it reaches the second line:

px = x * cs - y * sn; 
py = x * sn + y * cs;

Solution 3 - C++

Rotate by 90 degress around 0,0:

x' = -y
y' = x

Rotate by 90 degress around px,py:

x' = -(y - py) + px
y' = (x - px) + py

Solution 4 - C++

Sounds easier to do with the standard classes:

std::complex<double> vecA(0,1);
std::complex<double> i(0,1); // 90 degrees
std::complex<double> r45(sqrt(2.0),sqrt(2.0));
vecA *= i;
vecA *= r45;

Vector rotation is a subset of complex multiplication. To rotate over an angle alpha, you multiply by std::complex<double> { cos(alpha), sin(alpha) }

Solution 5 - C++

You're calculating the y-part of your new coordinate based on the 'new' x-part of the new coordinate. Basically this means your calculating the new output in terms of the new output...

Try to rewrite in terms of input and output:

vector2<double> multiply( vector2<double> input, double cs, double sn ) {
  vector2<double> result;
  result.x = input.x * cs - input.y * sn;
  result.y = input.x * sn + input.y * cs;
  return result;
}

Then you can do this:

vector2<double> input(0,1);
vector2<double> transformed = multiply( input, cs, sn );

Note how choosing proper names for your variables can avoid this problem alltogether!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondeceleratedcaviarView Question on Stackoverflow
Solution 1 - C++Sebastian Paaske TørholmView Answer on Stackoverflow
Solution 2 - C++Caspar KleijneView Answer on Stackoverflow
Solution 3 - C++AltivoView Answer on Stackoverflow
Solution 4 - C++MSaltersView Answer on Stackoverflow
Solution 5 - C++xtoflView Answer on Stackoverflow