jord-0.1.0.0: src/Data/Geo/Jord/NVector.hs
-- |
-- Module: Data.Geo.Jord.NVector
-- Copyright: (c) 2018 Cedric Liegeois
-- License: BSD3
-- Maintainer: Cedric Liegeois <ofmooseandmen@yahoo.fr>
-- Stability: experimental
-- Portability: portable
--
-- Types and functions for working with n-vectors.
--
module Data.Geo.Jord.NVector
( NVector(x, y, z)
, nvector
, cross
, dot
, norm
, scale
, unit
, zero
) where
import Data.Geo.Jord.Quantity
-- | Represents a position as the normal vector to the sphere.
data NVector = NVector
{ x :: Double
, y :: Double
, z :: Double
} deriving (Eq, Show)
-- | Add and subtract 'NVector's.
instance Quantity NVector where
add a b = NVector x' y' z'
where
x' = x a + x b
y' = y a + y b
z' = z a + z b
sub a b = NVector x' y' z'
where
x' = x a - x b
y' = y a - y b
z' = z a - z b
-- | Smart 'NVector' constructor. The returned 'NVector' is a 'unit' vector.
nvector :: Double -> Double -> Double -> NVector
nvector x' y' z' = unit (NVector x' y' z')
-- | Computes the cross product of the two given 'NVector's.
cross :: NVector -> NVector -> NVector
cross a b = NVector x' y' z'
where
x' = y a * z b - z a * y b
y' = z a * x b - x a * z b
z' = x a * y b - y a * x b
-- | Computes the dot product of the two given 'NVector's.
dot :: NVector -> NVector -> Double
dot a b = x a * x b + y a * y b + z a * z b
-- | Computes the norm of the given 'NVector'.
norm :: NVector -> Double
norm a = sqrt ((x a * x a) + (y a * y a) + (z a * z a))
-- | Multiplies each component of the given 'NVector' by the given value.
scale :: NVector -> Double -> NVector
scale a s = NVector x' y' z'
where
x' = x a * s
y' = y a * s
z' = z a * s
-- | Normalises the given 'NVector'.
unit :: NVector -> NVector
unit a = scale a s
where
s = 1.0 / norm a
-- | [0, 0, 0] - not a valid 'NVector', but can be used as the identity value during reduction.
zero :: NVector
zero = NVector 0.0 0.0 0.0