71 lines
1.7 KiB
Haskell
71 lines
1.7 KiB
Haskell
{-# LANGUAGE ScopedTypeVariables #-}
|
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
|
|
{- |
|
|
WARNING: orphan instances concerning Aeson classes and Linear.Quaternion datatypes have been introduced.
|
|
The warnings have been disabled.
|
|
-}
|
|
module Quaternion (
|
|
qID,
|
|
qz,
|
|
qToV3,
|
|
qToV2,
|
|
qToAng,
|
|
rotateToZ,
|
|
vToQuat,
|
|
comp,
|
|
prePos,
|
|
module Linear.Quaternion,
|
|
) where
|
|
|
|
import Geometry.Vector
|
|
import Data.Aeson
|
|
import Geometry.Data
|
|
import Geometry.Vector3D
|
|
import Linear.Quaternion
|
|
import qualified Linear.Quaternion as Q
|
|
|
|
instance ToJSON a => ToJSON (Q.Quaternion a) where
|
|
toEncoding = genericToEncoding defaultOptions
|
|
|
|
instance FromJSON a => FromJSON (Q.Quaternion a)
|
|
|
|
-- apply a rotation as if the z axis moves to the new point.
|
|
-- i think this may instead do as if the new point moves to be on z axis
|
|
rotateToZ :: Point3 -> Point3 -> Point3
|
|
rotateToZ z1
|
|
| cprod == V3 0 0 0 = id
|
|
| otherwise = Q.rotate $ Q.axisAngle cprod (angleVV3 z1 (V3 0 0 1))
|
|
where
|
|
cprod = crossProd z1 (V3 0 0 1)
|
|
|
|
vToQuat :: Point3 -> Point3 -> Q.Quaternion Float
|
|
vToQuat a b
|
|
| cprod == V3 0 0 0 = Q.axisAngle (V3 0 0 1) 0
|
|
| otherwise = Q.axisAngle cprod (angleVV3 a b)
|
|
where
|
|
cprod = crossProd a b
|
|
|
|
qToV3 :: Q.Quaternion Float -> Point3
|
|
qToV3 q = Q.rotate q (V3 1 0 0)
|
|
|
|
qToV2 :: Q.Quaternion Float -> Point2
|
|
qToV2 = (\(V3 x y _) -> V2 x y) . qToV3
|
|
|
|
qToAng :: Quaternion Float -> Float
|
|
qToAng = argV . qToV2
|
|
|
|
qID :: Q.Quaternion Float
|
|
qID = Q.axisAngle (V3 1 0 0) 0
|
|
|
|
comp :: Point3Q -> Point3Q -> Point3Q
|
|
comp (p,q) (p1,q1) = (p + Q.rotate q p1, q * q1)
|
|
|
|
prePos :: Point3Q -> Point3 -> Point3
|
|
prePos (p,q) p1 = p + Q.rotate q p1
|
|
|
|
qz :: Float -> Q.Quaternion Float
|
|
qz = Q.axisAngle (V3 0 0 1)
|
|
|
|
--deriving instance (Flat a => Flat (Quaternion a))
|