Hi @SimonDanisch, we at Roames (myself, @awbsmith and @c42f) have been using and thinking about quaternions, and there seems to be a few conceptual blockers to e.g. using *
as in you suggest in #3.
Primarily, a quaternion is a algebraic object, Quaternion{T} <: Number
, much like Complex{T} <: Number
. They form a ring, and algebraic operations +
and *
have a single unambiguous meaning. However, some quaternions, especially normalized quaternions, are useful for geometry, and it sure would be useful to implement rotations of 3-vectors.
I'm proposing that we break up the structure a little bit, so that Quaternion
is a pure algebraic number and UnitQuaternion
or RotationQuaternion
or similar is an object that either inherits from AbstractQuaternion
or else is a simple struct containing a Quaternion
.
As an exaple, we would want
Quaternion(1.0,2.0,3.0,4.0) * Vec(1.0,2.0,3.0) <: Vec{3,Quaternion{Float64}} # elementwise multiplication with standard multiplication rules
(you could replace Vec
with Vector
, Point
, any FixedVector
, etc).
and
RotationQuaternion(cos(t), sin(t), 0.0, 0.0) * Vec(1.0,0.0,0.0) == Vec(cos(t), sin(t), 0.0) # or whatever it is for this rotation...
For a simple gist, see here.
This would help us in Rotations.jl, plus clean up the whole interface for people who want to do either just algebra or just geometry. In fact, there is some small argument to say the algebraic part belongs outside of JuliaGeometry, but the simplest thing is to make a separation.