Shinmera / 3d-math

A library implementing the necessary linear algebra math for 2D and 3D computations

Home Page:https://shinmera.github.io/3d-math/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add to documentation a note about quaternion convention

KislyjKisel opened this issue · comments

q*q and maybe some other functions use the less popular Shuster's convention, which may be confusing to some. (Maybe add traditional variants?) (qmat uses the formula that is used with traditional quaternions (e.g. second element in the first column uses +, whereas with alternative convention - is used))

* (defvar q1 (qfrom-angle (vec3 0 1 0) (/ pi 2.0)))
* (defvar q2 (qfrom-angle (vec3 0 0 1) (/ pi 2.0)))
* (defvar v (vec3 0 0 1))
* (q* q1 v)
(VEC3 0.99999994 0.0 0.0)
* (q* q2 *)
(VEC3 0.0 0.9999999 0.0)
* (q* (q* q2 q1) v)
(VEC3 0.9999999 0.0 2.9802322e-8)
* (q* (alt-q* q2 q1) v)
(VEC3 0.0 0.9999999 2.9802322e-8)
* (q* (q* q1 q2) v)
(VEC3 0.0 0.9999999 2.9802322e-8)

Rotating (0 0 1) around (0 1 0) by pi/2 is (1 0 0) (as is); rotating (1 0 0) around (0 0 1) by pi/2 is (0 1 0), but if the two rotations are combined in RTL order then the result is (1 0 0). If the traditional (here alt-q*) multiplication is used then the result is correct. If the order is LTR then the result is correct as is. Quote from the current docstring for q*: "If a quaternion is passed, the rotations are combined in a right-to-left order". I've also confirmed (on 1 example only) that (q* q3 (q* (q* q1 q2) v)) = (q* (q* q1 q2 q3) v) = (q* (alt-q* q3 (alt-q* q2 q1)) v).

I've fixed the order issue in the presence of more than two quaternions. As for the convention I'm afraid you'll have to elaborate a bit for me to understand the issue.

The article "Quaternions and spatial rotation" on wikipedia states that there are 2 conventions used for quaternions and they have differently defined multiplication (and some other operations, the article mentions vector rotation and conversion to a matrix). q* in this library uses the one where there is a minus before the cross product: for example (+ (* yb za)) + (- (* zb ya)) is equal to the x component of the negated cross product. This corresponds to the alternative convention. There is a paper linked in the article that argues against using it to avoid confusion.