- Home /
Multiply quaternion by vector3... how is it done (mathematically)?
I'm not asking for a "transform.rotation * Vector3.forward = unit direction". What I am asking is more mathematical than that.
What are the mathematical steps taken in Unity by the * operator to multiply these matrices which are not uniform in dimension?
Because correct me if I'm wrong, but shouldn't it be impossible to multiply a 4x4 matrix with a 3x1 matrix, even when transposed to a 1x3 it should not be possible.
I am trying to form a better understanding of quaternions and spacial rotations.
I have indeed, but it doesn't say how Quaternion * Vector3 = Vector3
Answer by Golan2781 · Jan 01, 2013 at 09:58 AM
As the docs say, using Quaternion*Vector3 is shorthand for calling a Rotation by the Quaternion on the Vector3. It is not actually a Matrix multiplication; in fact, a quaternion is not a matrix, instead it is more akin to a four-dimensional complex number.
If you wish to know more about how Quaternions are used to generate rotations, Wikipedia's article is a good source. In short, you can think of the XYZW values of a Quaternion as a rotation axis vector described by XYZ and a rotation angle described by W. In order to apply the rotation defined by the quaternion to a Vector3, a standard 3X3 rotation matrix is formed from the quaternion XYZ similar as to how one would form a 3X3 rotation matrix from a set of Euler angles φϑψ. In both cases, the variable set defines a rotation but in order to be used, it must be transformed to a form appropriate for the space you are operating on - in this case, a 3X3 rotational matrix for 3-dimensional euclidean space.
The advantage of using quaternions is two-fold: First, while 'bigger' (four values instead of the three Euler ones) to store the rotation matrix can be calculated much faster as it does not require any trigonometric functions. Second, they avoid Gimbal Lock.
Please keep in mind that there is a reason you are repeatedly told not to modify quaternions by hand whenever looking into the issue! While not outright voodoo, a quaternion's data structure is rather complex and does not lend to natural understanding. In practically every case, the inbuilt functions provided for accessing and modifying quaternions will be easier, faster and more reliable than custom modifications!
AH I see, so essentially the quaternion is turned into this rotation matrix:
which is then applied to the forward vector which in turn gives the unit direction. I see I see.
I had trouble understanding the wikipedia article on its own as it just felt padded, I've never been good with walls of text but your simplified explanation helped me out a lot.
$$anonymous$$y reason for understanding this is not to have the ability to modify the quaternion but to understand rotations from quaternions. I am graduate games programmer, and there a many holes in my knowledge which I am trying to fill.
Glad to be of help. :)
Yes, think of the quaternion as similar to Euler angles - both describe a rotation but do not directly form the mathematical implementation in 3D.
Granted, the Wikipedia article is a bit much without a short explanation of the process. ^^
As @Golan2781 said, a quaternion represents an angle-axis rotation, where the axis is coded in XYZ and the angle in W (XYZ = axis unit vector sin(angle/2), W = cos(angle/2)). The quaternion multiplication is defined in math, and really results in a rotated vector (quaternion vector) or combined rotation (quaternion quaternion). Unity implements quaternion vector multiplication this way (thanks to the software ILSpy for this):
public static Vector3 operator *(Quaternion quat, Vector3 vec){
float num = quat.x * 2f;
float num2 = quat.y * 2f;
float num3 = quat.z * 2f;
float num4 = quat.x * num;
float num5 = quat.y * num2;
float num6 = quat.z * num3;
float num7 = quat.x * num2;
float num8 = quat.x * num3;
float num9 = quat.y * num3;
float num10 = quat.w * num;
float num11 = quat.w * num2;
float num12 = quat.w * num3;
Vector3 result;
result.x = (1f - (num5 + num6)) * vec.x + (num7 - num12) * vec.y + (num8 + num11) * vec.z;
result.y = (num7 + num12) * vec.x + (1f - (num4 + num6)) * vec.y + (num9 - num10) * vec.z;
result.z = (num8 - num11) * vec.x + (num9 + num10) * vec.y + (1f - (num4 + num5)) * vec.z;
return result;
}
Notice that the temporary variables num-something are the intermediate products 2xy, 2xw, 2x2, etc. of the rotation matrix above, and that they are combined with the Vector3 vec in a traditional 3x3 * 3x1 matrix multiplication.
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Rotating direction vectors 1 Answer
Snap a direction vector 1 Answer
Rotate camera around player 2 Answers
How to convert quaternion to vector3 with specific multiplication order? 5 Answers