{- Haskell Dynamics Engine, Copyright (C) 2007 Ruben Henner Zilibowitz All rights reserved. Email: rubenz@cse.unsw.edu.au Web: www.cse.unsw.edu.au/~rubenz This is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License that is include with this package in the file LICENSE-GPL.TXT. -} -- Quaternions -- Code by Ruben Henner Zilibowitz -- Created on 20/3/07 module Quaternions where data (RealFloat a) => Quaternion a = Q !a !a !a !a deriving (Eq, Read, Show) instance RealFloat a => Num (Quaternion a) where fromInteger a = Q (fromInteger a) 0 0 0 (Q a b c d) + (Q a' b' c' d') = Q (a+a') (b+b') (c+c') (d+d') (Q a b c d) - (Q a' b' c' d') = Q (a-a') (b-b') (c-c') (d-d') (Q a b c d) * (Q a' b' c' d') = Q (a*a'-b*b'-c*c'-d*d') (a*b'+b*a'+c*d'-d*c') (a*c'+c*a'+d*b'-b*d') (a*d'+d*a'+b*c'-c*b') abs q = Q (magnitude q) 0 0 0 signum (Q 0 0 0 0) = 0 signum q@(Q a b c d) = let r = magnitude q in Q (a/r) (b/r) (c/r) (d/r) instance (RealFloat a) => Fractional (Quaternion a) where q / r = q * (inverse r) fromRational a = Q (fromRational a) 0 0 0 magnitude (Q a b c d) = sqrt (a*a + b*b + c*c + d*d) conjugate (Q a b c d) = Q a (-b) (-c) (-d) inverse (Q a b c d) = Q (a*r) (-b*r) (-c*r) (-d*r) where r = recip (a*a + b*b + c*c + d*d) normalise q@(Q a b c d) = Q (a*r) (b*r) (c*r) (d*r) where r = recip (magnitude q)