-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | 3d math including quaternions/euler angles/dcms and utility functions -- -- This is a port of my mathlib C library: -- `https://github.com/ghorn/mathlib` @package spatial-math @version 0.2.7.0 module SpatialMath -- | 3-2-1 Euler angle rotation sequence data Euler a Euler :: a -> a -> a -> Euler a [eYaw] :: Euler a -> a [ePitch] :: Euler a -> a [eRoll] :: Euler a -> a -- | doesn't require RealFloat, used for overloading symbolics class Floating a => ArcTan2 a arctan2 :: ArcTan2 a => a -> a -> a -- | 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 --rotateXyzAboutX :: Floating a => V3 a -> a -> V3 a -- | 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) --rotateXyzAboutY :: Floating a => V3 a -> a -> V3 a -- | 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 --rotateXyzAboutZ :: Floating a => V3 a -> a -> V3 a -- | 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}
--
euler321OfQuat :: (ArcTan2 a, Ord a) => Quaternion a -> Euler a
-- | 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}
--
euler321OfDcm :: (Ord a, ArcTan2 a) => M33 a -> Euler a
-- | 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}
--
unsafeEuler321OfDcm :: ArcTan2 a => M33 a -> Euler a
-- | Convert Euler angles to quaternion
--
-- -- >>> 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) --quatOfEuler321 :: (Floating a, Ord a) => Euler a -> Quaternion a -- | 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) --dcmOfQuat :: Num a => Quaternion a -> M33 a dcmOfQuatB2A :: Num a => Quaternion a -> M33 a -- | 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)
--
dcmOfEuler321 :: Floating a => Euler a -> M33 a
-- | 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.7071067811865477 (V3 (-0.0) (-0.0) 0.7071067811865474) ---- --
-- >>> let s = sqrt(2)/2 in quatOfDcm $ V3 (V3 s s 0) (V3 (-s) s 0) (V3 0 0 1) -- Quaternion 0.9238795325112868 (V3 (-0.0) (-0.0) 0.3826834323650898) --quatOfDcm :: Floating a => M33 a -> Quaternion a quatOfDcmB2A :: Floating a => M33 a -> Quaternion a -- | vec_b = R_a2b * vec_a rotVecByDcm :: Num a => M33 a -> V3 a -> V3 a -- | vec_a = R_a2b^T * vec_b rotVecByDcmB2A :: Num a => M33 a -> V3 a -> V3 a -- | vec_b = q_a2b * vec_a * q_a2b^(-1) vec_b = R(q_a2b) * vec_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 -- | A 3x3 matrix with row-major representation type M33 a = V3 (V3 a) -- | A 3-dimensional vector data V3 a :: * -> * V3 :: ~a -> ~a -> ~a -> V3 a -- | Quaternions data Quaternion a :: * -> * Quaternion :: ~a -> {-# UNPACK #-} ~(V3 a) -> Quaternion a instance SpatialMath.ArcTan2 GHC.Types.Double instance SpatialMath.ArcTan2 GHC.Types.Float module SpatialMathT class Rotation p a | p -> a compose :: Rotation p a => Rot f1 f2 p -> Rot f2 f3 p -> Rot f1 f3 p rot :: Rotation p a => Rot f1 f2 p -> V3T f1 a -> V3T f2 a rot' :: Rotation p a => Rot f1 f2 p -> V3T f2 a -> V3T f1 a toDcm :: Rotation p a => Rot f1 f2 p -> Rot f1 f2 (M33 a) transpose :: Rotation p a => Rot f1 f2 p -> Rot f2 f1 p newtype Rot f1 f2 r Rot :: r -> Rot f1 f2 r [unR] :: Rot f1 f2 r -> r newtype V3T f a V3T :: V3 a -> V3T f a [unV] :: V3T f a -> V3 a -- | A space that has at least 1 basis vector _x. class R1 (t :: * -> *) -- |
-- >>> V1 2 ^._x -- 2 ---- --
-- >>> V1 2 & _x .~ 3 -- V1 3 --_x :: (R1 t, Functor f) => (a -> f a) -> t a -> f (t a) -- | A space that distinguishes 2 orthogonal basis vectors _x and -- _y, but may have more. class R1 t => R2 (t :: * -> *) -- |
-- >>> V2 1 2 ^._y -- 2 ---- --
-- >>> V2 1 2 & _y .~ 3 -- V2 1 3 --_y :: (R2 t, Functor f) => (a -> f a) -> t a -> f (t a) _xy :: (R2 t, Functor f) => (V2 a -> f (V2 a)) -> t a -> f (t a) -- | A space that distinguishes 3 orthogonal basis vectors: _x, -- _y, and _z. (It may have more) class R2 t => R3 (t :: * -> *) -- |
-- >>> V3 1 2 3 ^. _z -- 3 --_z :: (R3 t, Functor f) => (a -> f a) -> t a -> f (t a) _xyz :: (R3 t, Functor f) => (V3 a -> f (V3 a)) -> t a -> f (t a) type M33T f1 f2 a = V3T f1 (V3T f2 a) cross :: Num a => V3T f a -> V3T f a -> V3T f a orthonormalize :: Floating a => Rot f1 f2 (M33 a) -> Rot f1 f2 (M33 a) instance Data.Binary.Class.Binary r => Data.Binary.Class.Binary (SpatialMathT.Rot f1 f2 r) instance Data.Serialize.Serialize r => Data.Serialize.Serialize (SpatialMathT.Rot f1 f2 r) instance GHC.Generics.Generic (SpatialMathT.Rot f1 f2 r) instance GHC.Generics.Generic1 (SpatialMathT.Rot f1 f2) instance GHC.Classes.Ord r => GHC.Classes.Ord (SpatialMathT.Rot f1 f2 r) instance GHC.Show.Show r => GHC.Show.Show (SpatialMathT.Rot f1 f2 r) instance GHC.Classes.Eq r => GHC.Classes.Eq (SpatialMathT.Rot f1 f2 r) instance GHC.Real.Fractional r => GHC.Real.Fractional (SpatialMathT.Rot f1 f2 r) instance GHC.Num.Num r => GHC.Num.Num (SpatialMathT.Rot f1 f2 r) instance Foreign.Storable.Storable r => Foreign.Storable.Storable (SpatialMathT.Rot f1 f2 r) instance Data.Traversable.Traversable (SpatialMathT.Rot f1 f2) instance Data.Foldable.Foldable (SpatialMathT.Rot f1 f2) instance GHC.Base.Functor (SpatialMathT.Rot f1 f2) instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (SpatialMathT.V3T f a) instance Data.Serialize.Serialize a => Data.Serialize.Serialize (SpatialMathT.V3T f a) instance GHC.Generics.Generic (SpatialMathT.V3T f a) instance GHC.Generics.Generic1 (SpatialMathT.V3T f) instance GHC.Classes.Ord a => GHC.Classes.Ord (SpatialMathT.V3T f a) instance GHC.Show.Show a => GHC.Show.Show (SpatialMathT.V3T f a) instance GHC.Classes.Eq a => GHC.Classes.Eq (SpatialMathT.V3T f a) instance GHC.Real.Fractional a => GHC.Real.Fractional (SpatialMathT.V3T f a) instance GHC.Num.Num a => GHC.Num.Num (SpatialMathT.V3T f a) instance Foreign.Storable.Storable a => Foreign.Storable.Storable (SpatialMathT.V3T f a) instance Linear.Metric.Metric (SpatialMathT.V3T f) instance Linear.Vector.Additive (SpatialMathT.V3T f) instance GHC.Base.Applicative (SpatialMathT.V3T f) instance Data.Traversable.Traversable (SpatialMathT.V3T f) instance Data.Foldable.Foldable (SpatialMathT.V3T f) instance GHC.Base.Functor (SpatialMathT.V3T f) instance Linear.V1.R1 (SpatialMathT.V3T f) instance Linear.V2.R2 (SpatialMathT.V3T f) instance Linear.V3.R3 (SpatialMathT.V3T f) instance GHC.Num.Num a => SpatialMathT.Rotation (Linear.Quaternion.Quaternion a) a instance GHC.Num.Num a => SpatialMathT.Rotation (Linear.Matrix.M33 a) a