packages feed

gloss-examples-1.7.2.1: raster/Ray/Vec3.hs

{-# 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 #-}