Odd Quaternion Implementation

I’ve searched the forum and could not find any discussion on this.

The textbook definition for the inverse of a quaternion is the conjugate of the quaternion divided by its magnitude squared. So (in Python):

qInv = q.conjugate() / q.lengthSquared()

qInv.invertFrom(q) yields a decidedly different result.

The other thing I’ve noticed is that q1 * q2 performs the operation backwards from the textbook definition (it implements q2 * q1).

Am I nuts or is there a reason for this? Are there other oddities I should be watching out for?

I don’t think you can say there is really a single textbook definition. There are many different books with many different opinions on this subject. With matrices, Euler angles, as well as quaternions, there are always conflicting opinions on many of the implementation details; order of multiplication is one classic example.

In Panda’s implementation, the quaternion inverse does seems to be a looser definition than that which you quote: in fact, it is only the conjugate. This means that it will yield the same results as what you seek if the original quaternion is already normalized.


Perhaps there is not a single definition but I’ve yet to come across the one Panda uses. wolfram.com, wikipedia, numerous sites related to 3d programming, and the 3d mathematics textbook I own all agree on the inverse definition I provided (and that Panda’s multiplication is backwards).

I can make do with how Panda3d is implemented but the standard it is following is not documented. Perhaps the documentation should either include the mathematic definitions it is following or a link to an appropriate reference. As it stands now I can only hope that I’ve uncovered all the differences.

Finally I’m not sure your description of what Panda does for the inverse is even what it is doing. On my system q inverse is negative q conjugate which as best as I can tell does not even satisfy the basic mathematical requirement that q * qi == Identity [1]. Bug maybe?

mathworld.wolfram.com/Quaternion.html is a nice reference on quaternions with numerous mathematical references provided dating back 150 years.

[1] According to Hamilton the guy who invented Quaternions see page 121 of books.google.com/books?id=fIRAAA … al&f=false

Good points. Would you like to submit a patch to correct the quaternion math?


I’m running from the v1.72 debian 64 binary install at the moment so I can’t easily implement/test a patch nor confirm that this problem is in the latest 1.8 dev build. I want to switch to 1.8 dev to get multi-core rendering support but was put off by the ‘Highly unstable, use with extreme caution!’ warning. Is it really that bad?

As far as developing a patch for the quaternion math, do you have a link that points to how to get started as a developer / build from source (on Linux)? I’ve looked around the site but I have not even found mention of where the code repositories are.

The 1.8 build is actually fairly stable; I think that warning is a bit of an exaggeration. However, I can assure you that LQuaternion::inverse() is the same in 1.8 as it is in 1.7.2.

The Panda3D source is hosted in CVS at SourceForge. Building from source is as easy as running “python makepanda/makepanda.py --everything”; see INSTALL-MK in the source repository for more information.


If Panda’s quaternion multiplications are indeed backwards how much existing code would break after the patch? I read Hamilton about 15 yrs ago while in San Francisco as I’d become interested in some of the “fringe science” physics theories that stated that the original conversion of Maxwell’s quaternion EM theories to vectors by Heaviside had lost a number of interesting features. Back then computer graphics was usually done only in vector form like in High School Geometry class to save on the extra multiplications with quaternions only used for operations like perspective and lens transforms. I can almost see the problems with patching this at such a late date, lenses broken, reflective waterplanes broken… etc.

any thoughts?

Lord Gengoro Kitsune

Yeah there clearly is a potential for a huge ripple effect. At present the inverse is wrong enough that changing it is probably appropriate even with some pain, especially since it is easy to find where it is used in code.

Multiplication is a lot more problematic because it is hard to find since it is an operator instead of a function call. I keep finding places that need corrections in my code base well after switching from my own Python based Quaternion library to Panda’s.

Maybe there is a way to to transition more smoothly by maintaining a backwards compatibility option.
from pandac.PandaModules import OldQuat as Quat
from pandac.PandaModues import *
Quat = OldQuat

I doubt there are enough people currently using Quat.invert for that to be a problem.