Copyright | (c) Artem Chirkin |
---|---|
License | BSD3 |
Maintainer | chirkin@arch.ethz.ch |
Safe Haskell | None |
Language | Haskell2010 |
Quaternion operations implemented for Floats and Doubles.
The types QDouble
and QFloat
have the same representation as corresponding `Vector t 4`.
This means, you can do a cheap conversion between the types.
However, arithmetic instances, such as Num and Floating are implemented in substentially different ways. For example, fromInteger fills a vector fully but sets only real part to a quaternion:
>>>
1 = vec4 1 1 1 1
>>>
1 = packQ 0 0 0 1
All other numeric operations for vectors are element-wise, but for quaternions I have implemented the actual quaternion math. Some of the operations (such as trigonometric operations) are ambiguous for quaternions; the general rules I follow:
- Preserve imaginary vector axis same if possible;
- If both
+q
and-q
are possible, prefer real value positive (re q >= 0
).
Synopsis
- class Quaternion t where
- data Quater t
- packQ :: t -> t -> t -> t -> Quater t
- unpackQ :: Quater t -> (t, t, t, t)
- fromVecNum :: Vector t 3 -> t -> Quater t
- fromVec4 :: Vector t 4 -> Quater t
- toVec4 :: Quater t -> Vector t 4
- square :: Quater t -> t
- im :: Quater t -> Quater t
- re :: Quater t -> Quater t
- imVec :: Quater t -> Vector t 3
- taker :: Quater t -> t
- takei :: Quater t -> t
- takej :: Quater t -> t
- takek :: Quater t -> t
- conjugate :: Quater t -> Quater t
- rotScale :: Quater t -> Vector t 3 -> Vector t 3
- getRotScale :: Vector t 3 -> Vector t 3 -> Quater t
- axisRotation :: Vector t 3 -> t -> Quater t
- qArg :: Quater t -> t
- fromMatrix33 :: Matrix t 3 3 -> Quater t
- fromMatrix44 :: Matrix t 4 4 -> Quater t
- toMatrix33 :: Quater t -> Matrix t 3 3
- toMatrix44 :: Quater t -> Matrix t 4 4
- type QDouble = Quater Double
- type QFloat = Quater Float
Documentation
class Quaternion t where Source #
Quaternion operations
Quaternion data type. The ordering of coordinates is x y z w
,
where w
is an argument, and x y z
are components of a 3D vector
packQ :: t -> t -> t -> t -> Quater t Source #
Set the quaternion in format (x,y,z,w)
unpackQ :: Quater t -> (t, t, t, t) Source #
Get the values of the quaternion in format (x,y,z,w)
fromVecNum :: Vector t 3 -> t -> Quater t Source #
Set the quaternion from 3D axis vector and argument
fromVec4 :: Vector t 4 -> Quater t Source #
Set the quaternion from 4D vector in format (x,y,z,w)
toVec4 :: Quater t -> Vector t 4 Source #
Transform the quaternion to 4D vector in format (x,y,z,w)
square :: Quater t -> t Source #
Get scalar square of the quaternion.
> realToFrac (square q) == q * conjugate q
im :: Quater t -> Quater t Source #
Imagine part of quaternion (orientation vector)
re :: Quater t -> Quater t Source #
Real part of the quaternion
imVec :: Quater t -> Vector t 3 Source #
Get imagenery 3D vector of the quaternion
taker :: Quater t -> t Source #
Real part of the quaternion into number
takei :: Quater t -> t Source #
i-th component
takej :: Quater t -> t Source #
j-th component
takek :: Quater t -> t Source #
k-th component
conjugate :: Quater t -> Quater t Source #
Conjugate quaternion (negate imaginary part)
rotScale :: Quater t -> Vector t 3 -> Vector t 3 Source #
Rotates and scales vector in 3D using quaternion.
Let q = (cos (a/2), sin (a/2) * v)
; then the rotation angle is a
, and the axis of rotation is v
.
Scaling is proportional to |v|^2
.
>>>
rotScale q x == q * x * (conjugate q)
getRotScale :: Vector t 3 -> Vector t 3 -> Quater t Source #
Creates a quaternion q
from two vectors a
and b
.
rotScale q a == b
axisRotation :: Vector t 3 -> t -> Quater t Source #
Creates a rotation versor from an axis vector and an angle in radians. Result is always a unit quaternion (versor). If the argument vector is zero, then result is a real unit quaternion.
qArg :: Quater t -> t Source #
Quaternion rotation angle
>>>
q /= 0 ==> axisRotation (imVec q) (qArg q) == signum q
fromMatrix33 :: Matrix t 3 3 -> Quater t Source #
Create a quaternion from a rotation matrix.
Note, that rotations of q
and `-q` are equivalent, there result of this function may be
ambiguious. I decided to force its real part be positive:
>>>
taker (fromMatrix33 m) >= 0
fromMatrix44 :: Matrix t 4 4 -> Quater t Source #
Create a quaternion from a homogenious coordinates trasform matrix.
Ignores matrix translation transform.
Note, that rotations of q
and `-q` are equivalent, there result of this function may be
ambiguious. I decided to force its real part be positive:
>>>
taker (fromMatrix44 m) >= 0
toMatrix33 :: Quater t -> Matrix t 3 3 Source #
Create a rotation matrix from a quaternion.
Note, that rotations of q
and `-q` are equivalent, so the following property holds:
>>>
toMatrix33 q == toMatrix33 (-q)
toMatrix44 :: Quater t -> Matrix t 4 4 Source #
Create a homogenious coordinates trasform matrix from a quaternion.
Translation of the output matrix is zero.
Note, that rotations of q
and `-q` are equivalent, so the following property holds:
>>>
toMatrix44 q == toMatrix44 (-q)