Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quaternion and normalization

Tags:

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.

like image 332
Sebastian Krysmanski Avatar asked Jul 26 '12 10:07

Sebastian Krysmanski


People also ask

What does normalizing a quaternion do?

When normalized, a quaternion keeps the same orientation but its magnitude is 1.0. Note that this method will change the current quaternion. If you want to keep the current quaternion unchanged, use the normalized property instead. If this quaternion is too small to be normalized it will be set to Quaternion.

Are quaternions faster than matrices?

They also can offer better performance: Although a single rotation using a quaternion is a little slower than one using a matrix, when combining actions, quaternions can be up to 30% faster.

What does a quaternion represent?

A quaternion represents two things. It has an x, y, and z component, which represents the axis about which a rotation will occur. It also has a w component, which represents the amount of rotation which will occur about this axis. In short, a vector, and a float.

Why do games use quaternions?

Quaternions are mainly used in computer graphics when a 3D character rotation is involved. Quaternions allows a character to rotate about multiple axis simultaneously, instead of sequentially as matrix rotation allows.


1 Answers

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.

like image 175
David Hammen Avatar answered Oct 10 '22 04:10

David Hammen