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`

).

# Documentation

class Quaternion t where Source #

Quaternion operations

packQ, unpackQ, fromVecNum, fromVec4, toVec4, square, im, re, imVec, taker, takei, takej, takek, conjugate, rotScale, getRotScale, axisRotation, qArg, fromMatrix33, fromMatrix44, toMatrix33, toMatrix44

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)`