How Quaternions encode rotations: derivation and sample code
loopspace.mathforge.org
loopspace.mathforge.org
Matrices and trigonometry are in my opinion a pedagogically, conceptually, and practically poor way of understanding and using quaternions; furthermore, cross products (and the associated confusion about a right hand rule and polar vs. axial vectors and so on, not to mention a total failure to generalize to higher dimensions) need to vanish from the earth.
More generally, this is a topic that should be explained first using pictures, ideally interactive ones. The algebraic manipulations to formally prove what the pictures explain visually should just fill in the bookkeeping details.
Finally, perhaps the most important reason geometric (Clifford) algebras should be used for pedagogy, even if you plan to write code which only uses quaternions per se, is that they make the “sandwich” multiplication of versors as operators on vectors completely obvious as composition of reflections.
Also check out my implementation in Perl 6:
https://github.com/grondilu/clifford
With it, quaternions become:
use Clifford;
constant I = @e[1]*@e[2];
constant J = @e[2]*@e[3];
constant K = @e[1]*@e[3];
say I² == J² == K² == I*J*K == -1;The subalgebra using the pseudoscalar and the 1-blades can also represent quaternions.
You have to be careful using other people's implementations, because certain operations are anticommutative, so sign conventions and operand ordering matters a lot more. For instance, choosing whether K is defined as e3 * e1 rather than e1 * e3 depends on whether your base vectors square to 1 or -1.
Geometric Algebra is cool. It lets you say things like "the intersection of two spheres that don't touch is a circle with negative radius." You can't even represent a circle with negative radius in regular geometry.
Sure. For my implementation I thought a lot about how to deal with signatures and stuff. It's technically easy but making it simple and elegant is not obvious. I first thought about defining a @signature array, but then it occurred to me that it's much simpler to create two infinite spaces : one euclidean and one anti-euclidean. Later I've learned that Hestenes and others have considered this as well, they called it the mother of all geometric algebras, or universal geometric algebra[1]. Conveniently, Perl 6 deals with infinite lists very well, so it was very appropriate.
So in my implementation, @e[$i]² is +1 for all $i. If you want vectors with negative squares, use the @ē basis.
With geometric algebra, there are indeed several ways to represent quaternions. In fact there are several ways to represent complex numbers as well. I don't think it's a pitfall. As long as notations are clear and simple, it should be fine, I think.
1. https://en.wikipedia.org/wiki/Universal_geometric_algebra
For some notion of "regular geometry". Desargues could produce this result in the early 17th century by lifting the circles into right cones in three dimensions, though he would probably tell you that the circle with negative radius was meaningless.
There are a lot of great resources linked in this thread. My memory of the last time I took a dive into GA was that there was a split in the resources for representation -- one side tried to do everything axiomatically and symbolically, the other side had some concrete numbers but it was mysterious how they all worked together. Have you seen a super-basic resource that goes through the same sorts of modeling problems middle school and high school students do when first learning trig and classic geometry?
I did not know it was patented. My module does not specifically implement the conformal method, though. I did create two nul vectors and I called them no and ni, as in the conformal method, but that's about it. It's very much possible to do conformal geometric algebra with my module, but it's just not nearly as optimized as Versor is.
I've tried many times to implement Versor in Perl 6, but for various reasons I never succeeded. It's just kind of hard I guess. Also I'm not completely sure the optimization method I implemented is much worse, so it's hard for me to convince myself into doing the effort to improve it.
Also, I'm slightly skeptical the method used by Versor is the best that can be done, so again that dissuades me to do the effort.
I would love to see it done, though.
Whether they can replace the usual formulations in toto is another question, but they are certainly interesting.
Here’s the book to work through for anyone who wants to deeply understand rotation in classical mechanics problems: http://geocalc.clas.asu.edu/html/NFCM.html
I do still have vivid memories of working such problems out painfully using matrix/tensor methods in a college mechanics course 12 years ago though. :-)
The videos: https://www.youtube.com/channel/UCymE67THrWoeTABxzJm1wdg/vid...
The books: http://faculty.luther.edu/~macdonal/laga/index.html http://faculty.luther.edu/~macdonal/vagc/index.html http://www.geometricalgebra.net/
quick overview: http://faculty.luther.edu/~macdonal/GA&GC.pdf
Hestenes book "New Foundations in Classical Mechanics" is a great start, and there are books on GA in computer graphics. It is only a matter of time until there are solid software libraries and dedicated hardware for GA for it to really take off.
The current method is fine, and has done its job, however, when you read the history, and study GA, you realize the turn mathematics took. It was not based upon the better road, but on historical incidents.
Lectures start out by explaining the relation between complex numbers and rotations in the 2D plane, then discuss rotations in 3D using quaternions.
https://www.youtube.com/watch?v=uRKZnFAR7yw
https://www.youtube.com/watch?v=0_XoZc-A1HU
I'm no mathematician, so I'm not qualified to comment on this either. Would love to hear other opinions on this too.
My personal opinion on this is that his rational approach does produce beautiful math, in the sense that it is really simple and intuitive.
I think most of cases of "non acknowledging" are deeply personal aesthetic considerations. One likes to play with one set of objects and only with them.
In the widest sense existence in mathematics means that mathematical object is well-defined and the system used is consistent (you can't derive contradictions).
Of course mathematicians are free do limit themselves into any subset of axioms or concepts they feel is "natural" or "real" and work only with them. But if they make philosophical arguments against other using irrational numbers, axiom of choice etc. I think they should argue that they are not consistent or well defined.
Square roots are algebraic, not transcendental.
edit: Doing math without the real numbers is less elegant and harder, but it's philosophically more sound. It essentially means restricting yourself to math that can be described as a (possibly infinite) algorithm.
The lay person is more likely to agree with what Wildberger has to say than a mathematician. In fact, most people think that infinity in math is a process (potential infinity). But in math, we use absolute infinity. A completed infinity. 0.999... does not tend to 1, it _is_ 1. Infinity is completed.
I'm confused. My impression is that it is the other way around where irrational numbers and operations like sine, square root etc. are infinite 'algorithms'?
* In brief, you can convert a world vector v^μ into a Hermitian 2D complex matrix V by adjoining σ_0 = I to the standard Pauli matrices σ_{1,2,3} and then V = σ_μ v^μ, when you do this you find that actually det V = v_μ v^μ under the (+ − − −) signature. This means that for nullvectors det V = 0 and therefore V is a projection V = φ φ^†, else V is merely Hermitian with eigenvalues v_0 ± √(v_1² + v_2² + v_3²) (because it has trace 2v_0) and there's not much more you can say. Lorentz transforms are linear and preserve Hermitianness and the determinant, with the parity-reversing stemming from V → -V and V → (det V) V^{-1} and the rest being V → L V L^† for some L such that det(L) = 1. The special case where L^† L = 1 (which is SU(2)) of course corresponds to 3D rotations because it preserves trace hence v_0, so if it's also preserving det V then it must be preserving the eigenvalues and hence the Euclidean metric √(v_1² + v_2² + v_3²). In turn L can be seen to act directly on the φ of the null vectors, φ → L φ, so call those "spin vectors" and confirm that they are spinors by finding out that L = -I for any 360-degree rotation. This is the most direct way I know of to see that the Lorentz transforms are the group SL(2, C) with this nice SU(2) group embedded in there. Then you can square-root the metric into an orientation tensor on the C^2 vector space as [0, -1; 1, 0] and build up the rest of the algebra in reverse from that starting point.
Also check out http://geocalc.clas.asu.edu/pdf/LGasSG.pdf
By the way, it is possible to generalize the cross product to higher dimensions, it just won't be a nice binary product, in n dimensions you need n-1 vectors to uniquely determine one orthogonal to all of them. Of course you can achieve pretty much the same thing with the Clifford algebra, or with wedge products.
I consider the cross-product to be one of the most abused objects in Physics; my first course in Newtonian mechanics was a nightmare, filled as it were, with the ghosts of all the characters killed so as to make the plot ostensibly "simple".
Back a few years ago a friend and I were attempting to write a game engine. We hit many road blocks but what often killed us was fixing gimble lock. This isn't an issue for many things like FPSs or side scroller but when you get into the realm that we wanted to tackle (first person space flight) it becomes a challenge.
Quaternions, from my position as the ultimate laymen, take up the slack that Euler coordinates/angles have. The issue comes from rotating an object. Once the object is upside down, it's coordinate system stops working as you would expect. If you are head-to-floor upside down then your up relative to the world is down. When applying rotations that are based on shifts in pitch, yaw, and roll it is difficult to have correct behavior.
If instead of this, you implement quaternion rotations for all objects, this entire class of headache melts away. The problem is finding a good explanation of how this works or even yet how to implement it. It's what's stopped me dead in my tracks many times as the implementations often available still have many bugs (when in Space Engineers if you rotate your cursor a circle quickly you'll slowly rotate your character, this is a common bug in many implementations I've found)
I'm definitely going to read through all of this when I get back from uni today.
PS: Mathematicians/dark arts practicers, if I'm incorrect about anything I've said here please let me know and point me to where I can learn more
It helped me a lot to be explained quaternions starting from the complex plane. More specifically, by constructively inspecting their properties. There's a great interactive article that gets the pedagogy of teaching such a complex concept (pun definitely intended). Unfortunately, I can't seem to dig it up.
I recall the author's blog using all kinds of CSS and/or WebGL trickery to make 3d backgrounds – anyone know which blog I'm referring to?
Any reading will be helpful. Hope someone knows what you're referring to.
Edit: seems kind of like latitude and longitude. At latitude + or - 90, all longitudes map to the same point so that coordinate has no information.
In the general case Euler coordinates work much closer to our intuitions about rotation and orientation because the world we live in has a well-defined "down," as defined by gravity. Thus if you have a fixed "up" direction for the "camera", then any point on the sphere has a single corresponding orientation as long as you're not actually looking up/down (analogous to gimbal lock). This has the property that no matter what path your mouse takes, if you return to the same point, you will be oriented the exact same way you started.
This is not true with accumulating rotations in general. Try this with a paper airplane:
1. Hold it in the "flat" position at eye level and imagine the x, y, and z axis so that the x axis points out to the right, y points up, and z points down the tail and into your eye.
2. Pitch it 45 degrees nose up (counter-clockwise about the X axis).
3. Adjust your own perspective so that even though the plane is pitched up relative to the ground, you're looking at it as if once again x points right, y points up, and z points into your eye.
4. Now in this perspective, turn 45 the plane degrees counter-clockwise about the new Y axis. Note that this is not the same as "yaw", because new the Y axis you're using is actually 45 degrees off vertical from step #2.
5. Now without rotating the plane, reset your perspective. Notice how in addition to having pitched up and yawed left, your paper plane has also rolled slightly relative to the ground.
What you see in Space Engineers is probably this exact phenomenon. It's not so much a bug as it is a side effect of trying to come up with an intuitive rotation scheme when there is no "up".
Then the link with rotations becomes obvious and it gets very easy to transport geometric operations from the unit sphere to the rotation group (spherical linear interpolation, averaging, etc...)
More seriously, Lie group theory puts the light exactly on the shared structure between quaternions and rotations (both are smooth groups related in some way) and ignore the secondary details, so you spend time understanding what matters.
It may be more abstract, but you get more from your efforts in my opinion.
I think of it like this: a complex number represents a rotation in a plane. You need two "coordinates" to do that. 2d has one plane, but 3d has two planes - think about how an anti-air cannon rotates left-right and up-down. So, if we've got two rotations to represent, you must need two complex numbers - that's four "coordinates", or one quaternion.
Why not 3 planes?
to be completely honest, I'm not sure if this intuition is correct. But it seems to make sense
I then assumed that my idea with two rotations is how quaternions work. Here's to actually reading about a concept before I start explaining it next time...
And quaternions are made of two complex numbers.
edit: typo.
I don't pretend to grok quaternions (I only use them), but I'm fairly sure a quaternion consists of three imaginary numbers plus a real number.
Rotations in 2D are one-dimensional. Complex numbers are two-dimensional but we fix one degree of freedom by fixing the length.
Rotations in 3D are there-dimensional. Quaternions are four-dimensional but we fix the length again.
Just as in 2d with a complex, in 3d you can encode rotations with a 3d vector. The problem is that to reach any point from any other arbitrary point you can't use a single rotation, but a combination of two, sometimes three. Think about how your AAA gun operates or FPS viewpoint controls. Thus you start to use rotations along the three axes of a base which gives you a typical rotation matrix.
As soon as you start to compose rotations along axes you introduce a terrible phenomenon known as gimbal locking, where discontinuities appear especially near north and south poles.
And so, just as a 2D rotation in a plane can be represented by a vector orthogonal to that plane (i.e in a space outside the plane), the gimbal lock and all artifacts that are cumbersome when constraining ourselves in 3D can be dealt with by going up a dimension... Hence quaternions which encode+ a rotation by putting an arbitrary but well chosen axis and an amplitude in a space grown othrogonally to our 3D space.
+ Or isomorohically so
In general the number of real numbers needed to describe a rotation is the number of rotational degrees of freedom. This number is n(n - 1) / 2 in n dimensions, or C(n, 2), basically the number of orthogonal (2-)planes of rotation in R^n.
[0] https://en.wikipedia.org/wiki/Degrees_of_freedom_(mechanics)
Similarly, when a quaternion is defined as representing a translation, that is likewise 3 degrees of freedom in 4 numbers. The four numbers would be similar to a real cartesian translation with dX, dY, dZ, and a fourth number = sqrt( dX^2 + dY^2 + dZ^2 ).
It's like the 4th number is a checksum for the other 3. You are adding a fourth number to use a more elegant mathematical calculation, which automatically keeps the dependent data relationships intact, like magic.
How do you encode translations with quaternions? Don't you need dual quaternions for that?
There may also be a representation that also encodes distance from the origin, but I am probably confusing this in my memory with something else.
I guess if it makes sense to you, ok, but "continuous growth in a circle" to explain the complex exponential sounds like cloud-gazing to me: the human mind making up patterns where there are none.
The only way it makes sense to me is by looking at the power series and seeing how the exponential power series is almost the same as the sine and cosine power series (alternatively and equivalently: all of the exponential, hyperbolic, and circular functions satisfy almost the same differential equation).
Anyway, my point is that Euler's identity generalizes to any number that encapsulates "sideways" in Euclidean geometry. Any quaternion "x" that is a unit of rotation will satisfy "e^pi*x = -1". You can't get that easily from the power series understanding.
(I first got this picture from the Feynman lecture on algebra, http://www.feynmanlectures.caltech.edu/I_22.html, which doesn't seem to ever explain it that way explicitly. It's funny how memory works.)
Of course there's also value in looking deeper into the foundations.
For people interested, to use them in a C/C++ context, feel free to have a look at my Quaternion-Library.
It's a common practice to write libraries in C for flexibility, (many languages can ingest C) and use the 'extern "C"' for use in C++ code.
You can also write a thin C++ class wrapper for a more native object oriented interface.
It's funny people don't do this as much with other languages. For example, nobody describes pure Javascript as "js/html" even though you can have lots of js inside HTML code.
so at the bare minimum C/C++ will possibly increase your user base.
(edit)
You should not assume that C++ programmers are going to wade through your library code and rewrite your library with the proper signatures. You as the library writer should have done that and tested it, then advertised to prospective users that your library is ready for use with C++.
C is actually part of of the C++ standard. Within the ISO C++11 standard there is the C99 standard with some adjustments and exclusions. The integration is quite tight. So one can say C/C++ with some clarity.
Library writers often go thorough a lot of work to write extensive object oriented interfaces around C libraries. And they intend that the user use the C++ version not just import the C version in there C++ code. So in that case it is a necessity to use C/C++ because there are two separate interfaces.
In the general case I would guess that 'most' C programmers write some C++ and vise versa. So you have a very large overlap of C/C++ programmers. Objective C on the other hand is probably a significantly smaller group and is simply not big enough for C/C++ communities to think to much about.
That's not what I've seen. People usually either write C++ exclusively or C exclusively and hate the other language (probably more C writers that hate C++ than C++ writers that hate C).
Some people write very C-accented C++, with mallocs and frees instead of news and deletes and so forth (these are usually people who prefer C over C++ but are writing C++ for whatever reason). I guess those people could be said to be writing "C/C++". But in general I think people overestimate how close the two language communities are. What I have seen is that people like one language and deride the other.
However, you will never entirely avoid them because they are just too practical. Under careful constraints, they make code interfaces simpler.
This is especially important if you are to expose that code to a multidisciplinary team. There is no way you're going to teach an artist how quaternions work just so they can rotate their stuff around the up axis, when simple yaw-pitch angles cover 99% of their use cases.