Rotating a Vector in 3D Space
Asked Answered
A

2

80

I am making an android project in opengl es that uses accelerometer to calculate change in specific axes and my aim is to rotate my spacecraft-like object's movement vector. The problem is that i can't understand the math behind rotation matrices. Default movement vector is 0,1,0 , means +y, so the object looks upward in the beginning. and i am trying to rotate its movement vector so i can move the object where it points. I can gather rotation changes in phone. x-axis : rotate[0], y-axis : rotate[1], z-axis : rotate[2]. How can i rotate my movement vector using rotation matrix ?

Adame answered 30/1, 2013 at 15:31 Comment(1)
This HTML5 presentation on transforms explains transformations in greater detail with animations; it also explains how to handle complex transforms (concatenation of multiple elementary transforms) and also about transforming coordinate systems.Thermonuclear
T
251

If you want to rotate a vector you should construct what is known as a rotation matrix.

Rotation in 2D

Say you want to rotate a vector or a point by θ, then trigonometry states that the new coordinates are

    x' = x cos θ − y sin θ
    y' = x sin θ + y cos θ

To demo this, let's take the cardinal axes X and Y; when we rotate the X-axis 90° counter-clockwise, we should end up with the X-axis transformed into Y-axis. Consider

    Unit vector along X axis = <1, 0>
    x' = 1 cos 90 − 0 sin 90 = 0
    y' = 1 sin 90 + 0 cos 90 = 1
    New coordinates of the vector, <x', y'> = <0, 1>  ⟹  Y-axis

When you understand this, creating a matrix to do this becomes simple. A matrix is just a mathematical tool to perform this in a comfortable, generalized manner so that various transformations like rotation, scale and translation (moving) can be combined and performed in a single step, using one common method. From linear algebra, to rotate a point or vector in 2D, the matrix to be built is

    |cos θ   −sin θ| |x| = |x cos θ − y sin θ| = |x'|
    |sin θ    cos θ| |y|   |x sin θ + y cos θ|   |y'|

Rotation in 3D

In 3D we need to account for the third axis. Rotating a vector around the origin (a point) in 2D simply means rotating it around the Z-axis (a line) in 3D; since we're rotating around Z-axis, its coordinate should be kept constant i.e. 0° (rotation happens on the XY plane in 3D). In 3D rotating around the Z-axis would be

    |cos θ   −sin θ   0| |x|   |x cos θ − y sin θ|   |x'|
    |sin θ    cos θ   0| |y| = |x sin θ + y cos θ| = |y'|
    |  0       0      1| |z|   |        z        |   |z'|

around the Y-axis would be

    | cos θ    0   sin θ| |x|   | x cos θ + z sin θ|   |x'|
    |   0      1       0| |y| = |         y        | = |y'|
    |−sin θ    0   cos θ| |z|   |−x sin θ + z cos θ|   |z'|

around the X-axis would be

    |1     0           0| |x|   |        x        |   |x'|
    |0   cos θ    −sin θ| |y| = |y cos θ − z sin θ| = |y'|
    |0   sin θ     cos θ| |z|   |y sin θ + z cos θ|   |z'|

Note 1: axis around which rotation is done has no sine or cosine elements in the matrix.

Note 2: This method of performing rotations follows the Euler angle rotation system, which is simple to teach and easy to grasp. This works perfectly fine for 2D and for simple 3D cases; but when rotation needs to be performed around all three axes at the same time then Euler angles may not be sufficient due to an inherent deficiency in this system which manifests itself as Gimbal lock. People resort to Quaternions in such situations, which is more advanced than this but doesn't suffer from Gimbal locks when used correctly.

I hope this clarifies basic rotation.

Rotation and Revolution

The aforementioned matrices rotate an object at a distance r = √(x² + y²) from the origin along a circle of radius r; lookup polar coordinates to know why. This rotation will be with respect to the world space origin a.k.a revolution or orbiting. Usually we need to rotate an object around its own frame/pivot and not around the world's i.e. local origin. This can also be seen as a special case where r = 0. Since not all objects are at the world origin, simply rotating using these matrices will not give the desired result of rotating around the object's own frame. Instead you'd

  1. Translate the object to world origin
    • Object's origin would align with world's, making r = 0
  2. Rotate with one (or more) aforementioned rotation matrices
  3. Translate object back again to its previous (original) location.

The order in which the transforms are applied matters.

Composition/Concatenation of Transforms

Since matrices can represent not just rotation but also translation, scale, etc. all three operations in Rotation and Revolution section can be written as matrices. When they are multiplied we get a single matrix which does all three operations in order. The resultant matrix when multiplied with the points of an object will rotate the object around its axis (in its local space). Combining multiple transforms together is called concatenation or composition.

I urge you to read about linear and affine transformations and their composition to perform multiple transformations in one shot, before playing with transformations in code. Without understanding the basic maths behind it, debugging transformations would be a nightmare. I found this lecture video to be a very good resource. Another resource is this tutorial on transformations that aims to be intuitive and illustrates the ideas with animation (caveat: authored by me!).

Rotation around Arbitrary Vector

A product of the aforementioned matrices should be enough if you only need rotations around cardinal axes (X, Y or Z) like in the question posted. However, in many situations you might want to rotate around an arbitrary axis/vector. The Rodrigues' formula (a.k.a. axis-angle formula) is a commonly prescribed solution to this problem. However, resort to it only if you’re stuck with just vectors and matrices. If you're using Quaternions, just build a quaternion with the required vector and angle. Quaternions are a superior alternative for storing and manipulating 3D rotations; it's compact and fast e.g. concatenating two rotations in axis-angle representation is fairly expensive, moderate with matrices but cheap in quaternions. Usually all rotation manipulations are done with quaternions and as the last step converted to matrices when uploading to the rendering pipeline. See Understanding Quaternions for a decent primer on quaternions.

Thermonuclear answered 30/1, 2013 at 17:2 Comment(17)
If some one is interested in the reason behind gimbal lock: sundaram.wordpress.com/2013/03/08/…Thermonuclear
Please keep in mind that Quaternions doesn't solve the Gimbal lock and has nothing to do with it. Quaternions and Matrices are just encodings for the actual rotation/orientation. The cause of gimbal lock is not the encoding but the sequential rotation. Using quaternions to represent 3 euler angles will cause gimbal lock.Georgia
Agreed. Orientation representation is different from slerp (animation). Euler angles suffer from gimbal lock and matrices, axis-angle, quaternions can be used to avoid gimbal lock, when used rightly (by avoiding rotation concatenation).Thermonuclear
Gimbal lock arises from representating a rotation transform as multiple component rotations about different axes -- aka Euler angles. This scenario allows you to rotate one axis onto another, resulting in a loss of a degree of freedom and the dreaded gimble lock. One needs to represent 3D rotations with 1 and only one quaternion and not 3. Then use that for interpolation and compositing, which effectively avoids gimbal lock. For further detail refer Quaterions and their Applications to Rotation in 3D Space.Thermonuclear
That's exactly what I was trying to say. In the end quaternions are usually converted to matrices (for the renderer). That implies that again the encoding is not the problem, but actually losing a degree of freedom after each rotation.Georgia
Actually the original wording is from OpenGL forums by a guru member, the credit goes to him :) And thanks to you for bringing this up here.Thermonuclear
+1 Thank you for being positive while taking my criticism ( A lot of people actually doesn't take it with open mind especially I lack the rep.)Georgia
@Thermonuclear What would the solution be with radians?Derogative
@Brendon A measured angle can be written in different units e.g. degrees, radians, turns, etc. The unit doesn't change the technique (it's like asking will the directions to school from home change because I'm measuring distance by kilometres instead of miles now). Construction of a rotation matrix would still be the same -- just use the right implementation of sin and cos or convert the units to the one expected by these functions.Thermonuclear
but how to rotate around a vector tho?Swum
@JuneWang Added a new section to address rotation around an arbitrary axes. Hope it helps.Thermonuclear
@Glenn I hope your concern of not addressing rotation around arbitrary axes is now addressed. It wasn't originally put since the question wanted only rotation around cardinal axes. SO isn't a reference but a tutorial IMHO. Good pedagogy involves showing examples when teaching something; 2D rotations are discussed for this reason. Also to understand any rotation formula polar coordinates is essential. These build up the mental model and hence are not unwarranted.Thermonuclear
@Thermonuclear Quaternions is only for vectors in terms of i', j' and k', no?Swum
@June Sorry, I'm unable to understand your question. Quaternions are like 4-vectors but they've their own algebra; it's made of a 3-vector (imaginary) and a scalar (real). A tuple of any 4 real numbers is a quaternion. Usually a 3-vector <x, y, z> is converted to a quaternion thus <x, y, z, 0>.Thermonuclear
@legends2k, Does the Rodrigues' formula protect against the GIMBAL LOCK ?Perrault
@Perrault It depends on how you use it; generally it's not the representation it's how you use it. See comment by concept3d above.Thermonuclear
@legends2k, just simple question: Is it possible to make rotations ORDER and VALUE (valid) INDEPENDENT, for example ITEM.rotate( pi/2, pi, pi/2 ) // ( x,y,z ) or ( y,z,x ) or ( x,x,x ) and .... I NEED A FUNCTION WITH WHICH I COULD ROTATE AN 3D-OBJECT WITHOUT THINKING ABOUT VALUES AND ORDER around ARBITRARY POINT or EDGE that DOES NOT PASS THROUGH THE ORIGIN. -> Matrices: FAIL, Quaternion: maybe FAIL. SO WHAT TO USE in MY REQUIREMENTS ??? Thank you!Perrault
B
0

I have reasoned that the X component of your vector should be M*cos(o)cos(t)+x, Y component should be Mcos(t)sin(o)+y and the z component should be Mcos(o)*sin(t)+z where M is the magnitude of the vector, o is the angle of rotation in the vertical plane, t is the angle rotation in the horizontal plane, x is x value of the center of rotation, y is the y value of the center of rotation and z is the z value of the center of rotation. Please tell me if this works for you.

Barque answered 16/3, 2021 at 13:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.