{-# OPTIONS -fno-warn-missing-methods #-}
module Vec3
( Vec3(..)
, magnitudeV3
, normaliseV3
, mulsV3
, dotV3
, clampV3
, clipV3)
where
data Vec3
= Vec3 !Float !Float !Float
deriving (Eq, Show)
instance Num Vec3 where
(+) (Vec3 x1 x2 x3) (Vec3 y1 y2 y3)
= Vec3 (x1 + y1) (x2 + y2) (x3 + y3)
{-# INLINE (+) #-}
(-) (Vec3 x1 x2 x3) (Vec3 y1 y2 y3)
= Vec3 (x1 - y1) (x2 - y2) (x3 - y3)
{-# INLINE (-) #-}
(*) (Vec3 x1 x2 x3) (Vec3 y1 y2 y3)
= Vec3 (x1 * y1) (x2 * y2) (x3 * y3)
{-# INLINE (*) #-}
-- | Yield the magnitude of a vector.
magnitudeV3 :: Vec3 -> Float
magnitudeV3 (Vec3 x y z)
= sqrt (x * x + y * y + z * z)
{-# INLINE magnitudeV3 #-}
-- | Normalise a vector to have unit length.
normaliseV3 :: Vec3 -> Vec3
normaliseV3 v
= v `mulsV3` (1.0 / magnitudeV3 v)
{-# INLINE normaliseV3 #-}
-- | Multiply a vector by a scalar.
mulsV3 :: Vec3 -> Float -> Vec3
mulsV3 (Vec3 x1 y1 z1) s
= Vec3 (s * x1) (s * y1) (s * z1)
{-# INLINE mulsV3 #-}
-- | Compute the dot product of two vectors.
dotV3 :: Vec3 -> Vec3 -> Float
dotV3 (Vec3 x1 y1 z1) (Vec3 x2 y2 z2)
= x1 * x2 + y1 * y2 + z1 * z2
{-# INLINE dotV3 #-}
-- | Clamp a vectors components to some minimum and maximum values.
clampV3 :: Vec3 -> Float -> Float -> Vec3
clampV3 (Vec3 r g b) minVal maxVal
= Vec3 (clamp r) (clamp g) (clamp b)
where {-# INLINE clamp #-}
clamp x
| x <= minVal = minVal
| x >= maxVal = maxVal
| otherwise = x
{-# INLINE clampV3 #-}
-- | Clip a vector's components to some maxiumum value.
clipV3 :: Vec3 -> Float -> Vec3
clipV3 (Vec3 r g b) maxVal
= Vec3 (clip r) (clip g) (clip b)
where {-# INLINE clip #-}
clip x
| x > maxVal = maxVal
| otherwise = x
{-# INLINE clipV3 #-}