问题
I know that quaternions need to be normalized if I want to rotate a vector.
But are there any reasons to not automatically normalize a quaternion? And if there are, what quaternion operations do result in non-normalized quaternions?
- Multiplying two quaternions?
- Dot product?
Sorry, if this question is a little bit fuzzy. I'm still trying wrap my head around quaternions.
回答1:
Any operation that produces a quaternion will need to be normalized because floating-point precession errors will cause it to not be unit length.
I would advise against standard routines performing normalization automatically for performance reasons. Any competent programmer should be aware of the precision issues and be able to normalize the quantities when necessary - and it is not always necessary to have a unit length quaternion.
The same is true for vector operations.
回答2:
Late response; this answer is for people who come across this question in the future rather than for the questioner.
I disagree with the other two answers regarding only normalizing a quaternion occasionally. The standard formulae for using a quaternion to rotate/transform a vector or to generate a rotation/transformation matrix implicitly assume the quaternion is normalized. The errors that result from using an unnormalized quaternion are proportional to the square of the quaternion's magnitude. Quadratic error growth is something best avoided.
If you normalize frequently you don't need square root. A first order approximation works quite nicely. Here's what I use for quaternions as IEEE doubles, somewhat stylized:
double qmagsq = quat.square_magnitude();
if (std::abs(1.0 - qmagsq) < 2.107342e-08) {
quat.scale (2.0 / (1.0 + qmagsq));
}
else {
quat.scale (1.0 / std::sqrt(qmagsq));
}
Note that I'm using the first order Padé approximant 2.0/(1.0+qmagsq)
rather than the first order Taylor expansion 0.5*(3.0-qmagsq)
to estimate 1.0/std::sqrt(qmagsq)
. This approximation, if valid, replaces the square root call by a simple division. The key is to find when that approximation is valid, which is where that magic number 2.107342e-08 comes into play.
Why a Padé approximant? Two reasons. One is that for values of qmagsq
close to one, 1+qmagsq
loses less precision than does 3-qmagsq
. The other is that the Padé approximant cuts the error by a factor of three compared to the Taylor expansion. For values of qmagsq
between 0 and 2, the error in this approximation is less than (1-qmagsq)^2 / 8
. The magic number 2.107342e-08 represents where this error is more that half an ULP for IEEE doubles. If you are taking reasonable small steps, the square of the magnitude of the quaternion will always be within that limit. You'll never be calling sqrt
.
The one exception to this "normalize always" paradigm might be if you are using a Lie group integration technique to propagate quaternions. If you don't know what that means, you are probably using the equivalent of q(t+Δt) = q(t) + dq(t)/dt*Δt
to propagate a quaternion. You're still using that Euler step somewhere even if you are using a higher order integration technique that isn't a Lie group integrator.
回答3:
Funnily enough, building rotation matrices is one operation where normalizing quaternions is NOT needed, saving you one sqrt
:
M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y), 2*(w*y+x*z);
2*(w*z+x*y), w*w-x*x+y*y-z*z, 2*(-w*x+y*z);
2*(-w*y+x*z), 2*(w*x+y*z), w*w-x*x-y*y+z*z] / (w*w+x*x+y*y+z*z)
(in a MATLAB-ish notation) for the quaternion w+x*i+y*j+z*k
.
Moreover, if you are working with homogeneous coordinates and 4x4 transformation matrices, you can also save some division operations: just make a 3x3 rotation part as if the quaternion was normalized, and then put its squared length into the (4,4)-element:
M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y), 2*(w*y+x*z), 0;
2*(w*z+x*y), w*w-x*x+y*y-z*z, 2*(-w*x+y*z), 0;
2*(-w*y+x*z), 2*(w*x+y*z), w*w-x*x-y*y+z*z, 0;
0, 0, 0, w*w+x*x+y*y+z*z].
Multiply by a translation matrix, etc., as usual for a complete transformation. This way you can do, e.g.,
[xh yh zh wh]' = ... * OtherM * M * [xold yold zold 1]';
[xnew ynew znew] = [xh yh zh] / wh.
Normalizing quaternions at least occasionally is still recommended, of course (it may also be required for other operations).
回答4:
If a unit quaternion is obtained by numerically integrating its first time derivative, the integrator can automatically normalize it using a simple error feedback.
Let q represent a 4 by 1 column matrix of quaternions and dq its time derivative. Then sending dq+0.5(1-q.q)q/tau to the integrator in place of dq and using a suitable time constant tau will continuously normalize q. q.q represents the inner product.
I simulated a conservative, articulating Bricard mechanism floating in gravity-free space for 3.6 million seconds, which is nearly 42 days. Quaternions represented the floating base body's orientation. The total energy remained constant to within one part per million using a time constant tau of 0.5 seconds. An absolute error tolerance of 10^-12 and a relative error tolerance of zero was used in the numerical integrator DE.
http://www.amazon.com/Computer-Solution-Ordinary-Differential-Equations/dp/0716704617/
Quaternions are often obtained by numerical integration. If they are not normalized inside the integrator, then magnitude and phase errors will accumulate. A normalized quaternion moves along a unit sphere, and its first time derivative is tangent to that sphere. If the quaternion drifts away from the unit sphere, it will begin to accumulate phase errors that normalizing outside the integrator cannot correct. So the quaternion must be continuously normalized within the numerical integrator to minimize phase errors.
回答5:
your question is ambigious but if u need to normalize a quaternion is simple
q_normalized = q /square(norm(q))
with, q = q1 +q2i +q3 j +q4 k norm (q) = (q1)^2 + (q2)^2 + (q3)^2) + (q4)^4
if else explain to me your question
回答6:
Use of NONunit quaternions can be efficient.
Only few operations require unit length, for example interpolation.
Some tips:
- Creating and conversions to nonunit quaternions can be more efficient.
- Conversion to matrix from nonunit quaternion is still fast. Just compensate scale of quaternion squared.
- conversion matrix to nonunit quat is faster.
So it is not required to use only unit quaternions, it is just common practice. For every use case you can make decision use or not normalization. Personally i prefer to use nonunit quaternions.
WARNING: often, working with unit quaternions, we forget about numerical errors. For example, converting from/to matrix quaternion and thinking that it still unit make big numerical unstability, matrix is scaled , quaternions extracted is invalid. You can easy make such experiment.
来源:https://stackoverflow.com/questions/11667783/quaternion-and-normalization