Let say I have q^(1/3) which is 1/3 power of quaternion q.
Mathematically we can define
log q = [0 alpha*n], n is the rotation axis.
exp q = [cos(alpha) n*sin(alpha)], alpha is the rotation angle.
Quaternion Exponentiation is defined down below.
q^(t) = exp(t log q)
Quaternion QuaternionExp(Quaternion q, float t)
{
Quaternion
newQ = q;
float currentAngle
= Mathf.Acos(newQ.w);
// At the moment newQ's x, y, z has normal and already
applied sin(w)
// q' = exp(t * log q)
// log q = [0 alpha*n]
// exp p = [cos(alpha) n*sin(alpha)]
float newAngle =
currentAngle * t; // cos(alpha) term
// what / Mathf.Sin(currentAngle) does is extract
normal vector from the appllied nx, ny, nz
float newX =
newQ.x / Mathf.Sin(currentAngle) * Mathf.Sin(newAngle);
float newY =
newQ.y / Mathf.Sin(currentAngle) * Mathf.Sin(newAngle);
float newZ =
newQ.z / Mathf.Sin(currentAngle) * Mathf.Sin(newAngle);
newQ.x =
newX;
newQ.y =
newY;
newQ.z =
newZ;
newQ.w =
Mathf.Cos(newAngle);
return newQ;
}
|
QuaternionExp is the implementation of Quaternion Exponentiation in C#.
Like I mentioned that we have 45 degree rotation quaternion q.
Quaternion q = Quaternion.Euler(0, 45, 0);
and 1/3 degree of 45 is 15 degree so if I take q^(1/3) then I'll have 15 degree rotation quaternion and I can apply it to gameobject.
Quaternion q = Quaternion.Euler(0, 45, 0);
// q is the 45 degree rotation.
// q^(1/3) will be 15 degree rotation.
q = QuaternionExp(q, 1.0f / 3.0f);
this.transform.localRotation = q;
|
Last thing I want to describe is why we took / Mathf.Sin(currentAngle) when we calculate newX, newY, newZ.
This is because newQ's x, y, z values are already applied sin(theta) which we needed to extract from the value. so we divide Sin(currentAngle) from all of the newQ's x, y, z and apply Sin(newAngle).
That's all!
No comments:
Post a Comment