Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data Euler a = Euler {}
- class Floating a => ArcTan2 a where
- rotateXyzAboutX :: Floating a => V3 a -> a -> V3 a
- rotateXyzAboutY :: Floating a => V3 a -> a -> V3 a
- rotateXyzAboutZ :: Floating a => V3 a -> a -> V3 a
- euler321OfQuat :: (ArcTan2 a, Ord a) => Quaternion a -> Euler a
- unsafeEuler321OfQuat :: ArcTan2 a => Quaternion a -> Euler a
- euler321OfDcm :: (Ord a, ArcTan2 a) => M33 a -> Euler a
- unsafeEuler321OfDcm :: ArcTan2 a => M33 a -> Euler a
- quatOfEuler321 :: Floating a => Euler a -> Quaternion a
- dcmOfQuat :: Num a => Quaternion a -> M33 a
- dcmOfQuatB2A :: Num a => Quaternion a -> M33 a
- dcmOfEuler321 :: Floating a => Euler a -> M33 a
- quatOfDcm :: (Floating a, Ord a) => M33 a -> Quaternion a
- quatOfDcmB2A :: (Floating a, Ord a) => M33 a -> Quaternion a
- rotVecByDcm :: Num a => M33 a -> V3 a -> V3 a
- rotVecByDcmB2A :: Num a => M33 a -> V3 a -> V3 a
- rotVecByQuat :: Num a => Quaternion a -> V3 a -> V3 a
- rotVecByQuatB2A :: Num a => Quaternion a -> V3 a -> V3 a
- rotVecByEuler :: (Floating a, Ord a) => Euler a -> V3 a -> V3 a
- rotVecByEulerB2A :: (Floating a, Ord a) => Euler a -> V3 a -> V3 a
- type M33 a = V3 (V3 a)
- data V3 a :: * -> * = V3 !a !a !a
- data Quaternion a :: * -> * = Quaternion !a !(V3 a)
Documentation
3-2-1 Euler angle rotation sequence
Functor Euler Source # | |
Applicative Euler Source # | |
Foldable Euler Source # | |
Traversable Euler Source # | |
(ArcTan2 a, Floating a, Ord a) => Rotation Euler a Source # | |
Eq a => Eq (Euler a) Source # | |
Data a => Data (Euler a) Source # | |
Ord a => Ord (Euler a) Source # | |
Show a => Show (Euler a) Source # | |
Generic (Euler a) Source # | |
Binary a => Binary (Euler a) Source # | |
Serialize a => Serialize (Euler a) Source # | |
Generic1 * Euler Source # | |
type Rep (Euler a) Source # | |
type Rep1 * Euler Source # | |
class Floating a => ArcTan2 a where Source #
doesn't require RealFloat, used for overloading symbolics
arctan2 :: a -> a -> a Source #
arctan2 y x
computes the arctangent from two arguments. The
Double
and Float
instances call out to a sufficiently recent
version of libm
to compute this.
The following test cases are the full set of recommended
function properties specified for function atan2Pi()
on page 45
of the IEEE Std 754-2008 document.
>>>
arctan2 0 (-0) :: Double
3.141592653589793>>>
arctan2 (-0) (-0) :: Double
-3.141592653589793>>>
arctan2 0 0 :: Double
0.0>>>
arctan2 (-0) 0 :: Double
-0.0
\x -> x < 0 ==> arctan2 (-0) x == (-pi :: Double)
\x -> x < 0 ==> arctan2 0 x == (pi :: Double)
\x -> x > 0 ==> arctan2 (-0) x == (-0 :: Double)
\x -> x > 0 ==> arctan2 0 x == (0 :: Double)
\y -> y < 0 ==> arctan2 y (-0) == (-pi / 2 :: Double)
\y -> y > 0 ==> arctan2 y 0 == (pi / 2 :: Double)
\y -> y > 0 && not (isNaN y || isInfinite y) ==> arctan2 y (negate $ 1/0) == (pi :: Double)
\y -> y < 0 && not (isNaN y || isInfinite y) ==> arctan2 y (negate $ 1/0) == (-pi :: Double)
\y -> y > 0 && not (isNaN y || isInfinite y) ==> arctan2 y (1/0) == (0 :: Double)
\y -> y < 0 && not (isNaN y || isInfinite y) ==> arctan2 y (1/0) == (-0 :: Double)
\x -> not (isNaN x || isInfinite x) ==> arctan2 (negate $ 1/0) x == (-pi/2 :: Double)
\x -> not (isNaN x || isInfinite x) ==> arctan2 (1/0) x == (pi/2 :: Double)
>>>
arctan2 neginf neginf :: Double
-2.356194490192345>>>
arctan2 inf neginf :: Double
2.356194490192345>>>
arctan2 neginf inf :: Double
-0.7853981633974483>>>
arctan2 inf inf :: Double
0.7853981633974483
rotateXyzAboutX :: Floating a => V3 a -> a -> V3 a Source #
Rotate a vector about the X axis
>>>
trunc $ rotateXyzAboutX (V3 0 1 0) (pi/2)
V3 0.0 0.0 1.0
>>>
trunc $ rotateXyzAboutX (V3 0 0 1) (pi/2)
V3 0.0 (-1.0) 0.0
rotateXyzAboutY :: Floating a => V3 a -> a -> V3 a Source #
Rotate a vector about the Y axis
>>>
trunc $ rotateXyzAboutY (V3 0 0 1) (pi/2)
V3 1.0 0.0 0.0
>>>
trunc $ rotateXyzAboutY (V3 1 0 0) (pi/2)
V3 0.0 0.0 (-1.0)
rotateXyzAboutZ :: Floating a => V3 a -> a -> V3 a Source #
Rotate a vector about the Z axis
>>>
trunc $ rotateXyzAboutZ (V3 1 0 0) (pi/2)
V3 0.0 1.0 0.0
>>>
trunc $ rotateXyzAboutZ (V3 0 1 0) (pi/2)
V3 (-1.0) 0.0 0.0
euler321OfQuat :: (ArcTan2 a, Ord a) => Quaternion a -> Euler a Source #
Convert quaternion to Euler angles
>>>
euler321OfQuat (Quaternion 1.0 (V3 0.0 0.0 0.0))
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
>>>
euler321OfQuat (Quaternion (sqrt(2)/2) (V3 (sqrt(2)/2) 0.0 0.0))
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 1.5707963267948966}
>>>
euler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 (sqrt(2)/2) 0.0))
Euler {eYaw = 0.0, ePitch = 1.5707963267948966, eRoll = 0.0}
>>>
euler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 0.0 (sqrt(2)/2)))
Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
unsafeEuler321OfQuat :: ArcTan2 a => Quaternion a -> Euler a Source #
Convert quaternion to Euler angles. Returns Nan if 2.0*(q1*q3 - q0*q2) is outside [-1, 1].
>>>
unsafeEuler321OfQuat (Quaternion 1.0 (V3 0.0 0.0 0.0))
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
>>>
unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 (sqrt(2)/2) 0.0 0.0))
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 1.5707963267948966}
>>>
unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 (sqrt(2)/2) 0.0))
Euler {eYaw = 0.0, ePitch = NaN, eRoll = 0.0}
>>>
unsafeEuler321OfQuat (Quaternion (sqrt(2)/2) (V3 0.0 0.0 (sqrt(2)/2)))
Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
euler321OfDcm :: (Ord a, ArcTan2 a) => M33 a -> Euler a Source #
Convert DCM to euler angles
>>>
euler321OfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
>>>
euler321OfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
>>>
let s = sqrt(2)/2 in euler321OfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
Euler {eYaw = 0.7853981633974483, ePitch = -0.0, eRoll = 0.0}
unsafeEuler321OfDcm :: ArcTan2 a => M33 a -> Euler a Source #
Convert DCM to euler angles. Returns Nan if r[1,3] is outside [-1, 1].
>>>
unsafeEuler321OfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
Euler {eYaw = 0.0, ePitch = -0.0, eRoll = 0.0}
>>>
unsafeEuler321OfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
Euler {eYaw = 1.5707963267948966, ePitch = -0.0, eRoll = 0.0}
>>>
let s = sqrt(2)/2 in unsafeEuler321OfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
Euler {eYaw = 0.7853981633974483, ePitch = -0.0, eRoll = 0.0}
>>>
unsafeEuler321OfDcm $ V3 (V3 0 0 1.1) (V3 0 0 0) (V3 0 0 0)
Euler {eYaw = 0.0, ePitch = NaN, eRoll = 0.0}
quatOfEuler321 :: Floating a => Euler a -> Quaternion a Source #
Convert Euler angles to quaternion. The scalar part of the result may be positive or negative.
>>>
quatOfEuler321 (Euler 0 0 0)
Quaternion 1.0 (V3 0.0 0.0 0.0)
>>>
quatOfEuler321 (Euler (pi/2) 0 0)
Quaternion 0.7071067811865476 (V3 0.0 0.0 0.7071067811865475)
>>>
quatOfEuler321 (Euler 0 (pi/2) 0)
Quaternion 0.7071067811865476 (V3 0.0 0.7071067811865475 0.0)
>>>
quatOfEuler321 (Euler 0 0 (pi/2))
Quaternion 0.7071067811865476 (V3 0.7071067811865475 0.0 0.0)
dcmOfQuat :: Num a => Quaternion a -> M33 a Source #
convert a quaternion to a DCM
>>>
dcmOfQuat $ Quaternion 1.0 (V3 0.0 0.0 0.0)
V3 (V3 1.0 0.0 0.0) (V3 0.0 1.0 0.0) (V3 0.0 0.0 1.0)
>>>
let s = sqrt(2)/2 in fmap trunc $ dcmOfQuat $ Quaternion s (V3 0.0 0.0 s)
V3 (V3 0.0 1.0 0.0) (V3 (-1.0) 0.0 0.0) (V3 0.0 0.0 1.0)
>>>
dcmOfQuat $ Quaternion 0.9238795325112867 (V3 0.0 0.0 0.3826834323650898)
V3 (V3 0.7071067811865475 0.7071067811865476 0.0) (V3 (-0.7071067811865476) 0.7071067811865475 0.0) (V3 0.0 0.0 1.0)
dcmOfQuatB2A :: Num a => Quaternion a -> M33 a Source #
dcmOfEuler321 :: Floating a => Euler a -> M33 a Source #
Convert DCM to euler angles
>>>
fmap trunc $ dcmOfEuler321 $ Euler {eYaw = 0.0, ePitch = 0, eRoll = 0}
V3 (V3 1.0 0.0 0.0) (V3 0.0 1.0 0.0) (V3 0.0 0.0 1.0)
>>>
fmap trunc $ dcmOfEuler321 $ Euler {eYaw = pi/2, ePitch = 0, eRoll = 0}
V3 (V3 0.0 1.0 0.0) (V3 (-1.0) 0.0 0.0) (V3 0.0 0.0 1.0)
>>>
fmap trunc $ dcmOfEuler321 $ Euler {eYaw = pi/4, ePitch = 0, eRoll = 0}
V3 (V3 0.7071067811865476 0.7071067811865475 0.0) (V3 (-0.7071067811865475) 0.7071067811865476 0.0) (V3 0.0 0.0 1.0)
quatOfDcm :: (Floating a, Ord a) => M33 a -> Quaternion a Source #
convert a DCM to a quaternion
>>>
quatOfDcm $ V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)
Quaternion 1.0 (V3 0.0 0.0 0.0)
>>>
quatOfDcm $ V3 (V3 0 1 0) (V3 (-1) 0 0) (V3 0 0 1)
Quaternion 0.7071067811865476 (V3 0.0 0.0 0.7071067811865475)
>>>
let s = sqrt(2)/2 in quatOfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1)
Quaternion 0.9238795325112867 (V3 0.0 0.0 0.3826834323650898)
quatOfDcmB2A :: (Floating a, Ord a) => M33 a -> Quaternion a Source #
rotVecByQuat :: Num a => Quaternion a -> V3 a -> V3 a Source #
vec_b = q_a2b * vec_a * q_a2b^(-1) vec_b = R(q_a2b) * vec_a
rotVecByQuatB2A :: Num a => Quaternion a -> V3 a -> V3 a Source #
re-exported from linear
A 3-dimensional vector
V3 !a !a !a |
data Quaternion a :: * -> * #
Quaternions
Quaternion !a !(V3 a) |