-- 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 fork of Greg Horn's spatial-math package. It's reason for -- being is that its most recent version does not require deprecated -- packages. @package SpatialMath @version 0.2.7.1 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 :: Type -> Type) -- |
-- >>> V1 2 ^._x -- 2 ---- --
-- >>> V1 2 & _x .~ 3 -- V1 3 --_x :: R1 t => Lens' (t a) a -- | A space that distinguishes 2 orthogonal basis vectors _x and -- _y, but may have more. class R1 t => R2 (t :: Type -> Type) -- |
-- >>> V2 1 2 ^._y -- 2 ---- --
-- >>> V2 1 2 & _y .~ 3 -- V2 1 3 --_y :: R2 t => Lens' (t a) a _xy :: R2 t => Lens' (t a) (V2 a) -- | A space that distinguishes 3 orthogonal basis vectors: _x, -- _y, and _z. (It may have more) class R2 t => R3 (t :: Type -> Type) -- |
-- >>> V3 1 2 3 ^. _z -- 3 --_z :: R3 t => Lens' (t a) a _xyz :: R3 t => Lens' (t a) (V3 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 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 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 GHC.Num.Num a => SpatialMathT.Rotation (Linear.Quaternion.Quaternion a) a instance GHC.Num.Num a => SpatialMathT.Rotation (Linear.Matrix.M33 a) a instance Linear.V1.R1 (SpatialMathT.V3T f) instance Linear.V2.R2 (SpatialMathT.V3T f) instance Linear.V3.R3 (SpatialMathT.V3T f)