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 ?
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
- Translate the object to world origin
- Object's origin would align with world's, making r = 0
- Rotate with one (or more) aforementioned rotation matrices
- 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.
sin
and cos
or convert the units to the one expected by these functions. –
Thermonuclear <x, y, z>
is converted to a quaternion thus <x, y, z, 0>
. –
Thermonuclear 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.
© 2022 - 2024 — McMap. All rights reserved.