Haskell Code to Manipulate Quaternions Nov 26, 2015 Haskell code to manipulate Quaternions {- Quaternions.hs:manipulate Quaternions as Num -} module Quaternion where -- TODO: consider parameterizing Q data Q a = Q a a a a deriving (Eq) -- ^ ^ ^ ^ -- | i j k -- + real number instance (RealFloat a, Show a) => Show (Q a) where show q = sa ++ sb ++ sc ++ sd ++ send where a = getReal q b = getI q c = getJ q d = getK q sa = printTerm a "" sb = printTerm b "i" sc = printTerm c "j" sd = printTerm d "k" send = if a==0 && b==0 && c==0 && d==0 then "0" else "" printTerm a suffix | a == 0.0 = "" | otherwise = " + " ++ show a ++ suffix instance (RealFloat a) => Num (Q a) where -- return the sum of two quaternions (Q a1 b1 c1 d1) + (Q a2 b2 c2 d2) = Q (a1 + a2) (b1 + b2) (c1 + c2) (d1 + d2) -- return the difference between two quaternions (Q a1 b1 c1 d1) - (Q a2 b2 c2 d2) = Q (a1 - a2) (b1 - b2) (c1 - c2) (d1 - d2) -- return the product of two quaternions (Q a1 b1 c1 d1) * (Q a2 b2 c2 d2) = Q (a1*a2 - b1*b2 - c1*c2 - d1*d2) (a1*b2 + b1*a2 + c1*d2 - d1*c2) (a1*c2 - b1*d2 + c1*a2 + d1*b2) (a1*d2 + b1*c2 - c1*b2 + d1*a2) -- return the negation of a quaternion negate (Q a b c d) = Q (negate a) (negate b) (negate c) (negate d) -- return the norm of a quaternion -- TODO: fix this -- abs (Q a b c d) = sqrt (a*a + b*b + c*c + d*d) abs q = undefined -- TODO: what would a signum be for a Quaternion signum q = undefined -- return an integer as a quaternion fromInteger n = Q (fromIntegral n) 0.0 0.0 0.0 -- return the conjugate --conjugate :: Q -> Q conjugate (Q a b c d) = Q a (negate b) (negate c) (negate d) -- return the norm --norm :: Q -> Float norm :: (RealFloat a) => Q a -> a norm (Q a b c d) = sqrt (a*a + b*b + c*c + d*d) normalize q | n == 0.0 = error "norm is zero" | otherwise = (Q (1/n) 0.0 0.0 0.0) * q -- TODO: finish where n = norm q -- extract the real, i, j, k portions of a quaternion getReal (Q a b c d) = a getI (Q a b c d) = b getJ (Q a b c d) = c getK (Q a b c d) = d