How does it make sense to divide a vector by another? Can we at least multiply two vectors as well? (So that if the quaternion q is the vector a divided by the vector b, then q times b is a)
In a particular sense, division and subtraction are more general than their supposedly more primitive inverse operations.
For example, we can take the "difference" of two points to get a vector, i.e. the grocery store is in that direction, while it doesn't make much sense to add two points---this location plus the grocery store? Similarly with temperature (of a given scale), today can be 5 degrees hotter than yesterday, but saying "the total temperature between yesterday and today is 57 degrees" doesn't have a clear meaning.
So, in that vein, what operation transforms one 3D vector into another?
Well a combination of rotation and scaling, of course! There is some freedom in how you want to represent this scaling+rotation operation; we could use 3x3 matrices, meaning that the quotient of 3D vectors is reasonably described by a matrix. However, 3x3 matrices have 9 degrees of freedom, which is way overkill, since we just need 4 numbers: an axis (2 params), an angle, and a scale factor. For this reason, quaternions are a particularly natural representation of 3D vector division.
The general concept of division that we're getting at here has the terrible name "g-torsor". If you're not familiar with abstract algebra, though, the definition is not very enlightening. However, John Baez has a really accessible article[0] that comes to the rescue!
Side note: notice that in general, the results of division are different objects than the things doing the division. As such, it's somewhat unfortunate that we use the same units for both in many cases, e.g. temperature and temperature differences are really different things. Talking about units quickly turns into type theory, though, so I'll stop there.
It doesn't make sense in and of itself. We usually think
of division as a closed operation: we divide two things (like real numbers) and we get the same kind of thing out (another real number).
In Hamilton's original view of quaternions, he defined a "geometric quotient" of two 3d directed lines (one kind of object) as being a quaternion (another kind of object), and gave all sorts of complicated geometric formulas for how to calculate it.
> How does it make sense to divide a vector by another? Can we at least multiply two vectors as well?
Yes. That is the point of moving into the 4D complex space. This takes some higher level math, but I think it is essentially anyone can understand but just not taught in the standard coursework[0]. Here's a super quick crash course
This is all about how you abstractly define things like addition and multiplication. We'll call these actions an "operator". So you got these basic algebraic structures:
Group: a set (some numbers) and an operator (like + or *. I'll use ∘ to be general) that has associativity ( (a∘b)∘c = a∘(b∘c) ), an identity ( a∘=a ), and an inverse ( a∘ā=0 ). There's also closure which just means we don't create something that's outside the set ( ∀ a,b ∊ S, a∘b ∊ S )
Abelian Group: We also have commutativity ( a∘b=b∘a )
Ring: Think of as 2 groups. So we now have 2 operators ( ∘,▪ )[1]. This time ∘ is an Abelian Group and ▪ has closure, associativity ( (a▪b)▪c = a▪(b▪c) ), and is distributive with ∘ ( a∘(b▪c) = (a∘b)▪(a∘c) )
Field: Extend that ring so now ∘,▪ are both Abelian Groups (▪ got an identity element, an inverse, and commutativity), but we give an exception for the inverse on identity of ∘[2]
There's a lot more structures, but what we often really want is this Field thing. Our normal 1D numbers work work like that, the "every day" type of math. But think for a second, how do you do this same math in 2D? How do we make ab consistent? Well, you can't. At least not with our standard +,. So we introduce imaginary numbers. These numbers aren't imaginary so much as we're just changing the rule on +,* (∘,▪) to work differently. So we use imaginary numbers in 2D because it creates a field! You literally could do this with tuples as long as you remember the i^2 rule.
Now we extend this to 3D. Ops, we get a problem. Really no way to make ▪ () consistent here, especially around division. Bummer. We have a Ring.
But going up to 4D we can use a similar rule as to what we did in 2D and get a Field again! Now we can do consistent math. And this is actually why quaternions become useful for 3D rotation. But they can do a lot more, though come with some limitations as well.
This is super high level and just scratches the surface of all of this stuff but I hope it at least makes some sense here. Please ask questions and I'm also sure someone else will add some useful comments. But your question is completely normal and actually gets to the motivation of why kids these days are learning the difference between 39 and 93, despite having the same answer they do mean different things and understanding that earlier helps you when you get to abstract nonsense.
[0] It is taught later because this is when you first start getting into math as being about abstractions. You basically learn that you only ever learned one very specific kind of math and that all that breaks down. Your question is absolutely on point due to this. Like how you probably learned matrix multiplication and learned that AB ≠ BA
[1] Whatever ∘,▪ these will usually be referred to as "addition" and "multiplication" but just note that they aren't the same thing you're probably thinking of
[2] Let's return to less abstraction for a second. We have + and for (standard) addition and multiplication, right? 0 is the identity element for + and note that 0 doesn't have an inverse for multiplication. That is: we can't do a * (0^-1) = a/0. Note here that / is a shorthand for * with an inverse operator.
Also, "double" rotations, which have no analogue in 3D space. The extra degree of freedom in 4D lets you perform 2 orthogonal rotations. This means that you can rotate around in 4D space, leaving only the origin fixed. In 3D rotations always fix some axis.
Trying to think about this stuff can be mind-bending, since it's natural to try to visualize things. So to give a little intuition, consider the coordinates of a 4D vector (x,y,z,w) and notice that we can spin around in both the x-y and z-w planes at the same time without interfering with each other!
That’s nice. I’m interested in why you went for a complementary filter specifically, if it was enough for your purpose or just the first one you tried out. (I see you reference the ahrs package where there are also implementations for other attitude estimators.)
I don't why people get so excited about quaternions, like they are some mystical concept.
Personally, I think one is better off learning some Differential Geometry and Abstract Algebra to really appreciate the broader context in which these exist.
Hi! Author here. I hand wrote this website and the source code of the examples mostly comes from my own debugging tools. That method in particular is just a very minimal implementation of section 8.5.2 of this textbook (but I tried to make it friendly for the blog post).
I've been seeing "that's vibe coded" comments a lot lately on posts. Comments that call out code that may or may not be vibe-coded. At what point should these types of posts start getting down-voted? It's not constructive, and IMO imparts a negative connotation.
HN: Show HN Awesome New LLM can Code!!
Also HN: TFA is vibe coded angry pitchfork or ugh
I agree, this is becoming HN's new favourite way to detail a conversation unproductively. It's up there with doxxing and ad hominems in my opinion - unverifiable and usually antagonistic.
This looks more like a copy paste error, where the function signature requests xyz, but the function itself uses an undefined array "axis" of which xyz correspond to indexes 0-2.
The code is correct aside from the obvious bug.
Bugs predate the existence of AI by decades. This particular bug doesn't look like one an AI would write.
Also it's a short function. It's impossible to miss unused parame if you read your own code at all. And if you somehow don't... then it's deserved anyway.
I love vibe coding. Even the variables don't match (x, y, x vs axis[3]) and the coder is left with no knowledge what's they doing. You'll probably either prompt for fixing it or fix it yourself, but will still not get substantial amount of the domain knowledge -- and let's be honest, this is example just the simplest term there, that's why the code is so easy to correct even without thinking...
I just figured out from subcomments it's an excerpt from article, so my comment just doesn't fit here (thought author of the comment I replied to just braged they can vibe code something ad hoc and don't need to read about domain). Apologies for the mistake (still keeping my opinion about vibe coding).
A unit quaternion represents a rotation in R³.
A quaternion represents the quotient of two vectors in R³. That's what Hamilton had in mind.