{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
module PhysicsVectors
(
Vec(..)
, Vec3(..)
, Vec2(..)
) where
import GHC.Generics (Generic)
import Control.DeepSeq(NFData)
class (Num a, Floating b, Eq b) => Vec a b | a -> b where
fromScalar :: b -> a
dot :: a -> a -> b
normSq :: a -> b
normSq w = dot w w
norm :: a -> b
norm = sqrt . normSq
dist :: a -> a -> b
dist w w' = norm $ w - w'
unitVec :: a -> a
unitVec w = (1/norm w) `scalarMult` w
scalarMult :: b -> a -> a
scalarMult 0 _ = fromScalar 0
scalarMult s w = fromScalar s * w
data Vec3 a = Vec3 { x::a, y::a, z::a }
deriving (Eq, Ord, Show, Generic, NFData)
data Vec2 a = Vec2 { r :: Vec3 a, v :: Vec3 a }
deriving (Eq, Ord, Show, Generic, NFData)
instance (Eq a, Floating a) => Vec (Vec3 a) a where
fromScalar s = Vec3 s s s
dot a b = sum [ q a * q b | q <- [x, y, z]]
instance (Eq a, Floating a) => Vec (Vec2 a) a where
fromScalar s = Vec2 (fromScalar s) (fromScalar s)
dot a b = sum [ dot (q a) (q b) | q <- [r, v]]
instance Floating a => Num (Vec3 a) where
(Vec3 x1 y1 z1) + (Vec3 x2 y2 z2) = Vec3 (x1 + x2) (y1 + y2) (z1 + z2)
(Vec3 x1 y1 z1) * (Vec3 x2 y2 z2) = Vec3 (x1 * x2) (y1 * y2) (z1 * z2)
(Vec3 x1 y1 z1) - (Vec3 x2 y2 z2) = Vec3 (x1 - x2) (y1 - y2) (z1 - z2)
abs (Vec3 x1 y1 z1) = Vec3 (abs x1) (abs y1) (abs z1)
signum (Vec3 x1 y1 z1) = Vec3 (signum x1) (signum y1) (signum z1)
fromInteger i = Vec3 (fromInteger i) (fromInteger i) (fromInteger i)
instance Floating a => Num (Vec2 a) where
(Vec2 r1 v1) + (Vec2 r2 v2) = Vec2 (r1 + r2) (v1 + v2)
(Vec2 r1 v1) * (Vec2 r2 v2) = Vec2 (r1 * r2) (v1 * v2)
(Vec2 r1 v1) - (Vec2 r2 v2) = Vec2 (r1 - r2) (v1 - v2)
abs (Vec2 r1 v1) = Vec2 (abs r1) (abs v1)
signum (Vec2 r1 v1) = Vec2 (signum r1) (signum v1)
fromInteger i = Vec2 (fromInteger i) (fromInteger i)