Hacker News new | past | comments | ask | show | jobs | submit login
Quaternions: the Strange Numbers That Birthed Modern Algebra (quantamagazine.org)
205 points by rbanffy on Sept 7, 2018 | hide | past | favorite | 79 comments



Quaternions recently made me look pretty smart.

I was consulting at a company that's developing a VR real estate app, and the first thing I did was check to see whether they were calculating their rotations with quaternions.

It was easy to do, I just looked straight up and then turned my head to the right. My view rotated to the left, and I almost vomited. I immediately ripped the headset off and said, "You're using euler angles to calculate rotations, you need to use quaternions."

I felt pretty good about finding the biggest flaw in their system in 3 seconds.


Why are they using their own custom engine with a buggy VR integration in 2018? I assume they have some kind of business reason, but based on your story it seems like whatever engineer(s) they hired couldn't follow basic integration samples and documentation.


There are many reasons to not use Unity or Unreal. One major one being that they have restrictive licenses.

The best selling/best graphics fidelity (imo) VR game Lone Echo has its own custom game engine.


Even if you're writing your own engine from scratch, VR runtimes provide orientation information directly to the engine as a 4x4 transform matrix. They would have to ignore all the documentation and go far out of their way to somehow regress to euler angles, and are likely introducing other precision issues in doing so.


4x4 transform matrices typically represent 3-space transformations with homogeneous coordinates. Rotation matrices in this framework are effectively the same thing as Euler angles. They are not quaternions.


If you want to get pedantic they're also not euler angles, they're 4x4 transformation matrices.

You can pick out euler angles just as easily as calculating the quaternion by taking the basis vectors through the matrix and extracting it from there.


I'm aware of reasons for using a custom engine over Unity or Unreal, my question is what is this firms specific reason for not going that route. Also, Ready at Dawn has been developing that engine for years, and has world class engine programmers that know how to implement headtracking correctly, so the comparison isn't fair in this case.


> I was consulting at a company that's developing a VR real estate app, and the first thing I did was check to see whether they were calculating their rotations with quaternions.

You had better checked whether representations are represented via spin groups (which can be represented via Clifford algebras). These work in every dimension in opposite to quaternions.

EDIT: And via pin groups (also representable via Clifford algebras), also reflections can be reprented (recall that the composition of two reflections is a rotation and any rotation can be represented this way).


VR is by definition 3D, so quaternions should be enough, right? The reflections method could also be done with quaternions.

Full abstraction over dimension is certainly interesting, but often not necessary.


> Full abstraction over dimension is certainly interesting, but often not necessary.

Already the capability that is works both in 2D and in 3D is in my opinion reason enough.


What folks ship as a product is trivial quaternions.


Was it because of https://en.wikipedia.org/wiki/Gimbal_lock ?

Apollo 11 engineers made the same mistake. :)


For Apollo, it wasn't so much a "mistake" as a conscious decision to save weight. The Gemini IMU used 4 gimbals, and so avoided the issue entirely. Apollo dropped the weight of the extra gimbal and instead required the pilots to avoid flying in certain orientations.


I would characterize this more as a hardware engineering choice, with associated work around in software (don't rotate the spacecraft through gimbal lock/Euler angle singularity).

Disclaimer: IANARS


Yes large differences in orientation will make Euler angles gimbal lock. And it looks strange, even for small differences in orientation.

https://www.youtube.com/watch?v=Ocoibc7MoKg


The Shuttle program used quaternions, although the ISS apparently uses a definition that is easier to read by sight: http://webcache.googleusercontent.com/search?q=cache:-ivJED8...


I wrote a simple version of Google Earth for the Microsoft Surface in 2008 or so (back when Surface was a computer in the shape of a table with a touch interface). I felt pretty smart when I invented quaternions using matrices for rotating the globe, and then later realized what I was doing.


Yeah, no. If you're using matrix-based transforms, you're not using quaternions.

Edit: I'm oversimplifying. There's no reason you can't use both. But if you're exclusively using matrices, then by definition you're not using quaternions.


> I invented quaternions using matrices

what


I read that as "I was representing my dimensions as vectors and figured out a way to use 4D matricies for the math to work out and later found out that quaternions were a thing"


Am I correct suspecting quaternions were tensors?


I've found that the easiest way to understand quaternions is by visualizing them as scaled "look" or "orientation" vectors.

For example, if an airplane is oriented in the direction (x,y,z) at a rotation θ around that axis, then its rotation in quaternion form is cos(θ/2)+x sin(θ/2) i + y sin(θ/2) j + z sin(θ/2) k

Notice that the multiplications involving x, y, and z are just scaling the vector.

The other important thing to realize is that sin(θ/2) is greater than or equal to zero in the interval [0, 2*pi]. So a quaternion is just a look vector where the magnitude of the vector is determined by the rotation around the look vector axis.

See this page for a useful picture: http://www.chrobotics.com/library/understanding-quaternions


The easiest way to understand quaternions is as quotients of 3-dimensional vectors.

That is, if Q = u/v, then Q is the “quaternion” (complex sum of a scalar and a bivector) which rotates and scales v into u. Or written out, Qv = (u/v)v = u. The bivector part of Q has the same orientation as the plane spanning u and v.

If we want to use that quaternion as a representation of a general rotation of 3-dimensional space, we need to use a “sandwich product” because just multiplying Q directly by an arbitrary vector will rotate and scale the portion of the vector parallel to the plane of uv, but then also produce a trivector component from the perpendicular part of the vector, which is not what we wanted.

If we define R = √Q, then we can multiply any vector a like RaR`, where R` is the conjugate of R, and get the scaling & rotation operation we were looking for. Multiplication of any vector perpendicular to the plane of uv by this sandwich will just scale it by the magnitude of Q, but not change its direction, that is, for a vector b perpendicular to the plane of uv, RbR` = |Q|b, whereas for a vector c parallel to the plane of uv, RcR` = Qc, or in other words c gets rotated by the angle between v and u, as intended.

The square root here is where the half angle measures come from.


> The easiest way to understand quaternions is as quotients of 3-dimensional vectors.

Only for those who already know geometric algebra, I think. People coming from vector geometry and complex numbers will find other explanations much simpler.

Note also that your explanation in terms of a vector quotient is effectively a definition of vector quotients, and hence doesn't really explain.


Sure. You can’t only drop literally only my comment on someone who has never seen this subject before.

But in my experience, trying to explain the basics of 2- and 3-dimensional geometric algebra to someone followed by explaining quaternion rotation results in a lot less confusion (and might even save time overall, while resulting in dramatically richer understanding) versus trying to explain quaternions qua quaternions. It’s also very helpful for people who have worked with quaternions before in code but previously treated them as a mysterious black box.

If you explain how (multi)vector multiplication (Clifford product) works, then the behavior of quaternions can be clearly explained, and makes straight-forward geometrical sense.

If you just dive into talking about quaternions, they seem entirely arbitrary and mystical.

In neither case will the typical person be able to figure out what is going on instantly, without thinking about it for themselves.

Disclaimer: the above is based on my pretty limited, anecdotal experience. I would be interested to see a study try teaching e.g. undergraduates using two different formalisms, and see which group comes out with better understanding after a semester.


> The easiest way to understand quaternions...

....for who?


People that understand quaternions, seemingly.


Sort like monads I imagine as soon as you understand it you lose the ability to explain. I have given up "understanding" them and just try to understand when and where to use them.


That's OK! Do you think you really understand the natural numbers?


That's a good question, actually. I'm Not OP, I'm sure OP "understands" them as much as anyone does. But considering that the most common definition is an incomplete extrinsic definition by example, N = {1, 2, 3 ...}, I'd argue that in principle no complete extrinsic definition can be given :) That's more than a solipsism, because any number has inherent properties that make it different from all the others, even if these properties might be equal up to isomorphism with "n'th successor to zero", because then the system of isomorphisms is in question, begging the question ...

Whereas, if you know the intrinsic definition by the axioms, you know the definition, not the numbers. Big difference that is.

I'm keen on a distinction between numbers and forumals. If you take binary numbers and succ(), you have 0, 1 and an infinity of formulas. In my book that's only two natural numbers. We commonly change base to represent eg. 16 as 0x10 - or 1000 as 1k, requiring additional figures. Figure, number - potato, potato.


>I'm keen on a distinction between numbers and forumals.

What’s the operational advantage of this approach? I feel like it would wreck havoc with fundamental tools like mathematical induction..


The difference between f(x)=...=0 and x=2, e.g. is quite huge for a lot of college students. The distinction between constants, operators and formulas is quite explicit in algebra. It seems to be a natural distinction to make. One advantage, I guess, is that a formula can be wrong, but a number can't, which is why proof by induction works at all.


How would a proof by induction work with only two natural numbers?


Monads are (abstractions of) container types that allow you to map a function over the elements of the container, but return not just a new element but a entire new container.

    Just x => f x
    [x0,x1,...] => f x1 ++ f x2 ++ ...
    returnIO x => f x
What makes "magic monads" like IO useful is that you can feed internal state through them.

    thenIO (IO m) k = IO (\ s -> case m s of (# new_s, _ #) -> unIO k new_s)
    thenIO a b => c # forces a to be evaluated first to generate new_s
    # because b will refuse to preform any IO operations until it recieves new_s
    # this sequence is packaged up as c, which can be passed to other thenIO's
    # until it reaches a unsafePerformIO or the implicit not-so-unsafePerformIO underneath main
The 'state' (s,new_s,etc) of a IO object is just a placeholder to force in-order evaluation, but you could also store eg a Map of key-value pairs for a State monad.

(Note that this comes from someone who considers it a compilier bug if `* (char *)0 = -1` doesn't produce `mov byte[0], 0xFF`, so take the implementation details with a grain of salt.)


You shouldn't lose the ability to explain something when you understand it. There are things which require a significant amount of background knowledge to thoroughly understand, but that's a separate issue of retaining the ability to explain what they mean as you ascend the ladder of abstraction.

For example: I can say that a monad is an endofunctor which has been equipped with two structure-preserving transformations. This is correct, succinct and utterly tonedeaf unless I know that my audience has familiarity with the mathematical concepts of algebraic structures, categories of structures, the meaning of a functor, the meaning of an endofunctor, the meaning of a transformation and the meaning of "structure-preserving."

By being a little less terse I can provide a useful definition which is vastly more accessible. Start with the basics. A set A = {a, b, c} is a collection of objects. A function f: A --> B is a rule that sends one element a in set A to one element b in set B. Then we write f(a) = b, which is familiar from high school algebra. A set can consist of any kind of mathematical object - integers, rationals, reals, other sets, polynomials or even functions. Whatever you'd like.[1] Now we'll say a category is a collection of sets alongside all the functions that we can define on each pair of sets.

So let's take a category consisting of all possible sets of integers and all the possible functions that can be defined on any two of those sets of integers. Naively we can think of this category as a set of all sets of integers. Then the analogue of functions defined on sets is functors defined between categories. When dealing with functions, we can define a function on a single set so that f: A --> A means every element a of A is associated with another element of A. We can also do this with categories; this is called an endofunctor, and it essentially means it will send each object of our category to another object in the category. One way I could do this is by defining a relation that takes each set of positive integers in the category of integers and sends it to the exact same set consisting of negative integers. Each set {1, 2, 3, ...} will be sent to a set {-1, -2, -3, ...}; moreover, a function relating the set {a, b, c} and the set {x, y, z} will have a corresponding function relating the set {-a, -b, -c} to the set {-x, -y, -z} in on the other end of our functor.

So to recap, we have a category which consists of all possible sets of integers, and we've defined an endofunctor which maps any single object (set) in the category to another set within the same category - a functor defined on the category itself. Moreover, this endofunctor preserves relationships between respective sets at the function level. Now a natural transformation is a relationship between two different functors so that all the relationships that exist under the first functor also exist under the second functor. So with our current endofunctor, we might augment it with a natural transformation that transitions this functor from sets of integers to groups of integers, or rings of integers, or vector spaces of integers, etc. The respective definitions of those algebraic structures aren't germane to this explanation; basically what we're after here is the idea that we can take a functor between two like sets of elements in the same category of sets of elements and manipulate it so that if a in {a, b, c} relates to -a in {-a, -b, -c} in the same category, a will still relate to -a (and other relations on either side of the functor) after we've changed the functor to mean something slightly different.

Putting this all together: a monad a functor that sends every set in a category to another set within the same category and which has two natural transformations that "preserve" the relationships of the functor. What I've just explained is the mathematical sense of the word; the reason why this terminology is used in a language like Haskell is because it describes a very neat, abstract way of transforming one class of objects (e.g. strings) into another class of objects (e.g. integers). If we define a function for transforming any string into an integer and then we define two more functions for manipulating that function without invalidating its output, we have a functional monad. In functional programming this can be useful when we want to abstract away and compose functionality together.

Note that I'm not saying my explanation is perfect. It's greatly simplified. But it explains all the core concepts involved in the definition of a monad and it mostly does so from scratch.

_______________________

1. ...for this exercise. Please resist the temptation to bring up Russell's Paradox and ZFC.


As far as I understand it, quaternions are just matrixes for a 4-dimensional space. The 4-dimensional space is really just x/y/z/scale.


Since other people are giving their monad tutorials, I'll give my take here:

Haskell has a feature called type classes which allows you to overload functions. The definition of a type class gives a list of functions with their type signatures and names. When you write an instance of a type class, you must give implementations for the functions defined in the type class. All the functions that you define in the instance must match the type signature given in the type class definition.

Understand kinds is another critical prerequisite. Have you ever wondered what the type of a type is? Kinds are a simple construction that proves to be useful. Just as expressions have a type signature, a type expression has a kind signature. In its most basic form, a kind tells us how we can construct a type. We represent kinds by using asterisks * and kind functions ->. The asterisk is pronounced as "type".

The easiest way to understand kinds is by looking at a bunch of examples of types and type constructors. Monomorphic types such as Int and Bool have kind * . Type constructors are handled differently. An example of a type constructor is [] (list), which has kind * -> * . So list is a type constructor that takes in a type (which we represent with an asterisk), and returns another type. Therefore [Int] has kind * , since we applied the type Int to the list type constructor [], resulting in the type [Int]. Types constructors can also in some situations be partially applied, just like value constructors. Kinds are right associative, so the kind * -> * -> * is the same as * -> ( * -> * )

Here is a table of some types in Haskell with their kinds:

  +---------------------------------------+-----------------------+
  | Int                                   | *                     |
  +---------------------------------------+-----------------------+
  | Bool                                  | *                     |
  +---------------------------------------+-----------------------+
  | Maybe                                 | * -> *                |
  +---------------------------------------+-----------------------+
  | Either                                | * -> * -> *           |
  +---------------------------------------+-----------------------+
  | [] (list type)                        | * -> *                |
  +---------------------------------------+-----------------------+
  | -> (function type)                    | * -> * -> *           |
  +---------------------------------------+-----------------------+
  | a -> b                                | *                     |
  +---------------------------------------+-----------------------+
  | [Either Int Bool]                     | *                     |
  +---------------------------------------+-----------------------+
  | Either Int                            | * -> *                |
  +---------------------------------------+-----------------------+
  | (->) a                                | * -> *                |
  +---------------------------------------+-----------------------+
  | (,,,) (four element tuple)            | * -> * -> * -> * -> * |
  +---------------------------------------+-----------------------+
  | Mu where                              | ( * -> * ) -> *       |
  | newtype Mu f = In { out :: f (Mu f) } |                       |
  +---------------------------------------+-----------------------+

Now we are ready to look at the type class definition for monad:

  class Monad m where
    (>>=)  :: m a -> (a -> m b) -> m b
    (>>)   :: m a -> m b -> m b
    return :: a -> m a
On the first line, we give the name of the type class: Monad. This type class will be parameterized by a parameter named m. Based on how m is used in the function signatures, we deduce that m must have kind * -> * . This means that when we define an instance of the Monad type class, we tell what m should be. And m can be anything, as long as it has the kind * -> * ! In fact if we look at the table above, we can see that Maybe and the List type constructors have the required kind. If you've read any monad tutorials, these are often used as simple examples of monad instances.

The most important function in the monad type class is >>=, so let's focus on that. >>= is an infix function with two parameters, one of type "m a" and the other of type "a -> m b". The return type of >>= is "m b". So if we were to define a monad instance for m=Maybe, the type of that particular overloaded version of >>= has to be "Maybe a -> (a -> Maybe b) -> Maybe b". What should the definition of >>= be? Well it can be anything as long as the type signatures match up!

Take a look at the second parameter that has type "a -> m b". You can think of this as a sort of callback or continuation function. Typically the >>= function takes the first parameter (which has type "m a"), does some processing to unwrap the value, passes this value to the callback function and then takes this result and does some more processing before returning the result (which must have type "m b"). The >>= can call the callback function as many times as it wants (or maybe not at all). It could do anything, as long as the type signature matches up. There's one more detail that I've so far been ignoring: the overloaded functions need to follow some rules beyond the type signature constraint. These are called the monad laws, and you can find out more about them elsewhere by searching for "monad laws".

Why even bother with the Monad type class at all? It turns out that programmers have discovered many different programming patterns that seem to match up with these signatures. In fact, this particular pattern has become observed to be so common and useful that the authors of Haskell decided to provide some useful built in language operations to make them easier to use (do notation in Haskell). You can think of the >>= as a sort of programmable semicolon, where the overloaded bind operator is parameterized by a specific continuation function, but the overall program flow is dictated by the specific overloaded version of >>=.


I'm happy to see 3Blue1Brown's most recent video [0] get a mention in this article! He does a great job of explaining quaternions though visual intuition.

(I do think simply calling Grant a "math animator" is selling him a bit short. He's a true educator in every sense; animation is just one of the (very effective) learning aides he uses.)

[0] https://www.youtube.com/watch?v=d4EgbgTm0Bg


My first interaction with quaternions was by applying the same principles used for Julia fractals, creating really fascinating artistic renders. The hardware was incredibly slow back then, so now I'm interested in experimenting again to see how this could be implemented in a shader.

http://paulbourke.net/fractals/quatjulia/

The simple results above may just look like three dimensional blobs of taffy, but different rendering methods create some stunning effects. Additionally animating variations of these fractals is mesmerizing.

http://www.bugman123.com/Hypercomplex/

Hypercomplex fractals are simply beautiful.


Alright, tomorrow I want someone to count how many times we see the phrase "the easiest way to understand quaternions is ..." on here.


I don't think that's a bad thing -- it's people trying to test their mutual understanding.

Here, destroy my inexpert one, and maybe I'll learn something: "It's like describing how to twist a ball, first with the direction used to spear it with a rod, an then how much to twist."


I rather inelegantly attempted to describe this as "a twisty and a pushy" to a friend today, while mimicking the animation with my hands. There is no work-appropriate way to do this. :|


That flipped a couple switches in my head, at least. Now to mentally translate this back to the math. Thanks!


I rather like explanation, for what it’s worth.


Every time there's a math-y thing on Hacker News, there are many people who want to write comments to explain the math-y thing to each other :)


Absolutely and I wouldn't want it any other way! Repeated exposure is a great way to learn!

Besides, I haven't learned quaternions so maybe one of the explanations I read tomorrow will click!


At the very least, you should open this web page just to see the weird rotating cube with ribbons on all 4 faces animation. I'm not sure if there's a visual trick there or not.



True, that recommendation to look at the video.

I found the example in Feynman of using a single "ribbon" (a belt) connected to a book to be a much better example of a 720° rotational symmetry than this very cool and mesmerizing but also brain breaking video clip of the "ribbon cube"!


There's no trick. It's really unintuitive but it works.


Seems like the top and bottom ribbons would work. But the ribbons on the side get a kink every 2 rotations that the animation sort of sweeps under the rug?


They get a twist, but then loop around the cube, which undoes the twist. You can see their full orientation throughout the animation. (Or try getting your own cube and ribbons and try physically turning it to see for yourself.)


You can see the key behavior by fixing one end of a belt, and moving the free end.

You should find that there is a way to apply and remove double twists in the belt without twisting the free end.


That animation should be the new logo for the Brainfuck language.


Numberphile's explanation of Quaternions is the simplest I have seen so far:

https://www.youtube.com/watch?v=3BR8tK-LuB0

Quaternions are very important to know if you are doing any kind of 3D math. For instance, game programming or SLAM for robotics.


As a 3d character animator I try to use Quaternions on very few bones, the problem with Quaternions is not being able to edit the curves as a 1 to 1 understanding of the axis. I mainly use the Quaternions for IK handles and the Root bone, the things that will rotate more than 360 degress.


> the problem with Quaternions is not being able to edit the curves as a 1 to 1 understanding of the axis

Can you expand on this? What is the curve representing, and which axis do you mean?


Not the GP, but by axis they mean XYZ euler angles. In 3D animation software you typically have a set of curve graphs that show transformations vs time, that allow the animator to tweak timing, ease in/out of keyframes etc. If your object has its rotations animated as a quaternion you effectively lose this functionality, because the individual XYZW components of the 4D rotation don't correspond to anything intuitive in 3D space. So typically you want to keep your rotations in euler angles except in the special cases when you run into gimbal lock etc.


Okay, let's see if I have this right. The rotations are animated by manipulating the graphs of three functions of time, the values of which are the amounts of rotation around each coordinate axis?

The only rotation animations I've made have been done with code.


Pretty much. Usually you do the rough animation by manipulating the objects in the 3D viewport (with the manipulator using euler angles even in the cases where the angles are then converted to and stored as quaternions) and marking keyframes. The graph view is then useful for tweaking the interpolation between keyframes, minor adjustments, copying and pasting keyframes and such.

The graphs are time on X against rotation/translation/scale amount on Y, yes, with separate graphs for each axis.


Ive been recently studying dual quaternions which are even crazier

http://www.chinedufn.com/dual-quaternion-shader-explained/

They are THE formalism for representing translation and rotation since they interpolate super nicely.


You can just interpolate translation and orientation each individually (translation using linear interpolation, since it's an affine space, and orientation using SLERP or the matrix exponential and logarithm), and you should get the same thing as dual-quarternion interpolation.


Slerp is quaternionic interpolation.


It's not dual-quaternion anything, though.

(Also you can implement it with matrix logarithms and exponents, no unit quaternions necessarily needed)


Can you look into it first? Yes you can but dual quaternions are more suited for this.


I have looked into it, that's why I felt comfortable replying in the first place! ;)

Can you explain why dual quaternions are more suited and for what? I can understand the appeal of having "one number" to represent a rotation and translation. But the interpolation they provide is no different than if you interpolate the rotational and translational components independently, right?

By the way, the 2D analog of dual quaternions is dual complex numbers. They let you encode a translation and rotation (and scaling) in 2D, just as the dual quaternions do for 3D.

One thing that bothers me about dual quaternions, and you may have an answer to this, is that there's an 8th term that doesn't seem to buy you anything: the epsilon term (not multiplied by i, j, k). It's an 8-dimensional representation, whereas a quaternion + translation is a 7-dimensional representation.

For more information: http://www.euclideanspace.com/maths/algebra/realNormedAlgebr...

http://www.euclideanspace.com/maths/algebra/realNormedAlgebr...


The separation can be a problem if I want to for example do a Fourier transform.


A Fourier transform of what? If you have a reference, I'd love to learn more.


Hey can you email me? I’d like to continue this convo. My email is in my profile.


Lookup nonuniform Fourier.


Where could one learn quartenion math?

For educational purposes, I want to generate a 3d rotating cube on the screen without any help from 3d kits like OpenGL and etc (I want to learn all the math there is to do this without any help, only rastering).

Thanks in advance.


You will need more than quaternions to get a rotating cube working without OpenGL. You would need some kind of basic lighting for this to work.

If you really want to build a 3d engine from scratch without OpenGL, I suggest checking this book out. It was written in the mid 90s and explains how to write a simple 3d engine in DOS.

https://archive.org/details/BlackArt3DEBook


Well, I suppose you could create a wireframed cube without any lighting...

But the above material is much more interesting.


Try to find the papers from Ken Shoemake. He has an article in the book Graphics Gems IV ( ArcBall, Section III.1 ).

A long time ago I wrote a STL viewer that utilizes quaternions to compute the model rotations using what I learnt from those papers.

https://github.com/jimijimi/trekanter_mingw

Warning: Very UGLY code, so be easy on me( win32 cross compiled on Linux, ugh! ).


And if you take quaternions further, you end up with something you can generalize to any number of dimensions, which also unifies algebra and geometry in very nice ways: Clifford algebra.

https://slehar.wordpress.com/2014/03/18/clifford-algebra-a-v...

> Here we see the hierarchy of Clifford Algebras each with its own characteristic pattern of components, that appear in numbers corresponding to Pascal’s triangle. Two-dimensional clifs, Cl2 (the even sub-algebra) are mathematically isomorphic to complex numbers. Three-dimensional clifs, Cl3 are isomorphic to Pauli matrices used to model subatomic particles. Cl4 is isomorphic to Dirac matrices that model relativistic subatomic particles.

All of that assumes every element of the metric signature has the same sign; that is, the dot product of any basis vector with itself is always positive for all of them or negative for all of them. If you pick one dimension to have a sign opposite the others, that dimension is your time dimension and you're now in Minkowski space. The consequences of doing that is literally the entirety of Special Relativity.

If you construct a Clifford algebra in Minkowski space, that's Spacetime algebra:

https://arxiv.org/abs/1411.5002

> We present a comprehensive introduction to spacetime algebra that emphasizes its practicality and power as a tool for the study of electromagnetism. We carefully develop this natural (Clifford) algebra of the Minkowski spacetime geometry, with a particular focus on its intrinsic (and often overlooked) complex structure. Notably, the scalar imaginary that appears throughout the electromagnetic theory properly corresponds to the unit 4-volume of spacetime itself, and thus has physical meaning. The electric and magnetic fields are combined into a single complex and frame-independent bivector field, which generalizes the Riemann-Silberstein complex vector that has recently resurfaced in studies of the single photon wavefunction. The complex structure of spacetime also underpins the emergence of electromagnetic waves, circular polarizations, the normal variables for canonical quantization, the distinction between electric and magnetic charge, complex spinor representations of Lorentz transformations, and the dual (electric-magnetic field exchange) symmetry that produces helicity conservation in vacuum fields. This latter symmetry manifests as an arbitrary global phase of the complex field, motivating the use of a complex vector potential, along with an associated transverse and gauge-invariant bivector potential, as well as complex (bivector and scalar) Hertz potentials. Our detailed treatment aims to encourage the use of spacetime algebra as a readily available and mature extension to existing vector calculus and tensor methods that can greatly simplify the analysis of fundamentally relativistic objects like the electromagnetic field.

More prosaically, it allows you to write all of the Maxwell equations in a single equation.

http://www.av8n.com/physics/clifford-intro.htm


Seems like a wierd article trying to support octonions. I've graduated from quaternions using Lie Algebra/Groups (not that I understand them completely) but I find it much more general that it handles translations in a much better fashion.


If you like quaternions, you should check out the split-quaternions. They're equivalent to the 2x2 matrices, but help you understand them better by using analogies to the highly familiar and intuitive quaternions.


I get why Euler angles are not ideal (gimbal lock). But what are the advantages of quaternions over rotation matrices?


(From the point of view of graphics programming.)

The advantage/disadvantage of a 4x4 matrix (i.e. homogenous coordinates) is that you can describe the full transform--position, rotation, scale, and skew--in one go. If you only care about rotations, then using quaternions is less multiplication. Plus quaternions sidestep any issues with unwanted scale/skew if you're dealing with rigid-body objects.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: