-
Notifications
You must be signed in to change notification settings - Fork 26
Quaternion
A quaternion represents a three-dimensional rotation or reflection transformation. They are the preferred way to store and manipulate rotations in 3D applications, as they do not suffer the same numerical degredation that matrices do.
The quaternion constructor initializes to the identity transform:
>>> q = Quaternion() >>> q Quaternion(real=1.00, imag=<0.00, 0.00, 0.00>)
Internally, the quaternion is stored as four attributes: x
, y
and
z
forming the imaginary vector, and w
the real component.
Rotations can be formed using the constructors:
new_identity()
- Equivalent to the default constructor.
new_rotate_axis(angle, axis)
-
Equivalent to the Matrix4 constructor of the same name. angle is specified in radians, axis is an instance of Vector3. It is not necessary to normalize the axis. Example:
>>> q = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>)
new_rotate_euler(heading, attitude, bank)
-
Equivalent to the Matrix4 constructor of the same name. heading is a rotation around the Y axis, attitude around the X axis and bank around the Z axis. All angles are given in radians. Example:
>>> q = Quaternion.new_rotate_euler(math.pi / 2, math.pi / 2, 0) >>> q Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)
new_interpolate(q1, q2, t)
-
Create a quaternion which gives a (SLERP) interpolated rotation between q1 and q2. q1 and q2 are instances of Quaternion, and t is a value between 0.0 and 1.0. For example:
>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q2 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0)) >>> for i in range(11): ... print Quaternion.new_interpolate(q1, q2, i / 10.0) ... Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>) Quaternion(real=0.75, imag=<0.66, 0.09, 0.00>) Quaternion(real=0.78, imag=<0.61, 0.17, 0.00>) Quaternion(real=0.80, imag=<0.55, 0.25, 0.00>) Quaternion(real=0.81, imag=<0.48, 0.33, 0.00>) Quaternion(real=0.82, imag=<0.41, 0.41, 0.00>) Quaternion(real=0.81, imag=<0.33, 0.48, 0.00>) Quaternion(real=0.80, imag=<0.25, 0.55, 0.00>) Quaternion(real=0.78, imag=<0.17, 0.61, 0.00>) Quaternion(real=0.75, imag=<0.09, 0.66, 0.00>) Quaternion(real=0.71, imag=<0.00, 0.71, 0.00>)
Quaternions may be multiplied to compound rotations. For example, to rotate 90 degrees around the X axis and then 90 degrees around the Y axis:
>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q2 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0)) >>> q1 * q2 Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)
Multiplying a quaternion by a vector gives a vector, transformed appropriately:
>>> q = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0)) >>> q * Vector3(1.0, 0, 0) Vector3(0.00, 0.00, -1.00)
Similarly, any 3D object can be multiplied (e.g., Point3, Line3, Sphere, etc):
>>> q * Ray3(Point3(1., 1., 1.), Vector3(1., 1., 1.)) Ray3(<1.00, 1.00, -1.00> + u<1.00, 1.00, -1.00>)
As with the matrix classes, the constructors are also available as in-place
operators. These are named identity
, rotate_euler
and
rotate_axis
. For example:
>>> q1 = Quaternion() >>> q1.rotate_euler(math.pi / 2, math.pi / 2, 0) Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>) >>> q1 Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)
Quaternions are usually unit length, but you may wish to use sized
quaternions. In this case, you can find the magnitude using abs
,
magnitude
and magnitude_squared
, as with the vector classes.
Example:
>>> q1 = Quaternion() >>> abs(q1) 1.0 >>> q1.magnitude() 1.0
Similarly, the class implements normalize
and normalized
in the
same way as the vectors.
The following methods do not alter the quaternion:
conjugated()
-
Returns a quaternion that is the conjugate of the instance. For example:
>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q1.conjugated() Quaternion(real=0.71, imag=<-0.71, -0.00, -0.00>) >>> q1 Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>)
get_angle_axis()
-
Returns a tuple (angle, axis), giving the angle to rotate around an axis equivalent to the quaternion. For example:
>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q1.get_angle_axis() (1.5707963267948966, Vector3(1.00, 0.00, 0.00))
get_matrix()
-
Returns a Matrix4 implementing the transformation of the quaternion. For example:
>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0)) >>> q1.get_matrix() Matrix4([ 1.00 0.00 0.00 0.00 0.00 0.00 -1.00 0.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 1.00])