Quaternion
From EliteWiki
Contents |
[edit] Overview
A quaternion is a set of four values (W X Y Z) that are used in Oolite to specify a rotation in 3D space. To specify a particular rotation you need to think about the axis about which the rotation is made and the angle or amount by which the model is to be rotated.
For a given axis (x y z) and angle (a), the quaternion representing a rotation of a degrees around the axis from the origin (0,0,0) to (x,y,x) is:
W = cosine( 0.5 * a )
X = x * sine( 0.5 * a )
Y = y * sine( 0.5 * a )
Z = z * sine( 0.5 * a )
So a rotation of 90 degrees about the z axis (0 0 1) would be:
W = cosine ( 45 degrees ) = 0.707..
X = 0 * sine( 45 degrees ) = 0
Y = 0 * sine( 45 degrees ) = 0
Z = 1 * sine( 45 degrees ) = 0.707..
Now because quaternions are normalised (adjusted so that W * W + X * X + Y * Y + Z * Z = 1) when Oolite reads them in, you can multiply each part of a quaternion by the same value and still have it represent the same angle. So this rotation can also be represented as W = 1, X = 0, Y = 0, Z= 1 (let's use [1 0 0 1] as shorthand).
[edit] Examples
[edit] 90º turns about the z-axis
Oolite uses quaternions to specify rotations in some parts of shipdata.plist, most notably in the subentities part of an entry, like here in the relevant sub-entity entry for the Coriolis station:
Code:
<key>subentities</key> <array> <string>arc-detail 0 0 0 1 0 0 0</string> <string>arc-detail 0 0 0 1 0 0 1</string> <string>arc-detail 0 0 0 0 0 0 1</string> <string>arc-detail 0 0 0 1 0 0 -1</string> <array>
The last four numbers after the four 'arc-detail' lines are the W X Y and Z of quaternions representing rotations about the z-axis of 0 degrees, 90 degrees, 180 degrees, and 270 degrees (the first three numbers are the subentity's position relative to the station, in this case all are at the same place at the station's origin).
[edit] 120º turns about the z-axis
Similarly, the shipdata of the Weeviloid 2 illustrates how to place sub-entities at 3 equilateral points:
Code:
<key>subentities</key> <array> <string>weeviloid2-spine 0 0 0 1 0 0 0</string> <string>weeviloid2-spine 0 0 0 0.5 0 0 0.8660254</string> <string>weeviloid2-spine 0 0 0 0.5 0 0 -0.8660254</string> <array>
Given that the first entry (0 0 0 1 0 0 0) will place the sub-entity at the exact place that the model is situated (0 degrees), the next two lines reproduce it at 120 degrees and 240 degrees.
[edit] 22.5º turns about the z-axis
To display 16 sub-entities that join to make a ring, as done in the Ringpod and Torus shipdata, these are the relevant lines:
Code:
<key>subentities</key> <array> <string>torus_pod 0 0 0 1 0 0 0</string> <string>torus_pod 0 0 0 0.9808 0.0 0.0 0.1951</string> <string>torus_pod 0 0 0 0.9239 0.0 0.0 0.3827</string> <string>torus_pod 0 0 0 0.8315 0.0 0.0 0.5556</string> <string>torus_pod 0 0 0 0.7071 0.0 0.0 0.7071</string> <string>torus_pod 0 0 0 0.5556 0.0 0.0 0.83110</string> <string>torus_pod 0 0 0 0.3827 0.0 0.0 0.9239</string> <string>torus_pod 0 0 0 0.1951 0.0 0.0 0.9808</string> <string>torus_pod 0 0 0 0 0 0 1</string> <string>torus_pod 0 0 0 -0.1951 0.0 0.0 0.9808</string> <string>torus_pod 0 0 0 -0.3827 0.0 0.0 0.9239</string> <string>torus_pod 0 0 0 -0.5556 0.0 0.0 0.83110</string> <string>torus_pod 0 0 0 -0.7071 0.0 0.0 0.7071</string> <string>torus_pod 0 0 0 -0.8315 0.0 0.0 0.5556</string> <string>torus_pod 0 0 0 -0.9239 0.0 0.0 0.3827</string> <string>torus_pod 0 0 0 -0.9808 0.0 0.0 0.1951</string> <array>
Again the 0º sub-entity will appear with the 0 0 0 1 0 0 0, and the next 15 lines place it at 22.5º, 45º, 67.5º, 90º, 112.5º, 135º, 157.5º, 180º (with 0 0 0 0 0 0 1), 202.5º, 225º, 247.5º, 270º, 292.5º, 315º and 337.5º.
[edit] Quaternion calculus
To perform one rotation, and then another, one needs to multiply two quaternions together.
Multiplying quaternions isn't commutative: Qa x Qb does not equal Qb x Qa
To multiply Q1 (w1, x1, y1, z1) by Q2 (w2, x2, y2, z2):-
W = w1 x w2 - x1 x x2 - y1 x y2 - z1 x z2
X = w1 x x2 + x1 x w2 + y1 x z2 - z1 x y2
Y = w1 x y2 + y1 x w2 + z1 x x2 - x1 x z2
Z = w1 x z2 + z1 x w2 + x1 x y2 - y1 x x2
To determine the quaternion for a rotation of A degrees/radians around an axis defined by a vector (x, y, z)
W = cosine ( 0.5 x A)
X = x * sine (0.5 x A)
Y = y * sine (0.5 x A)
Z = z * sine (0.5 x A)

