vector-space-0.0: src/Data/AffineSpace.hs
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
----------------------------------------------------------------------
-- |
-- Module : Data.AffineSpace
-- Copyright : (c) Conal Elliott and Andy J Gill 2008
-- License : BSD3
--
-- Maintainer : conal@conal.net, andygill@ku.edu
-- Stability : experimental
--
-- Affine spaces.
----------------------------------------------------------------------
module Data.AffineSpace
(
AffineSpace(..), (.-^), distanceSq, distance, alerp
) where
import Data.VectorSpace
infix 4 .+^, .-^, .-.
class VectorSpace v s => AffineSpace p v s | p -> v s where
-- | Subtract points
(.-.) :: p -> p -> v
-- | Point plus vector
(.+^) :: p -> v -> p
-- TODO: consider replacing p and v with a type constructor argument:
--
-- class VectorSpace' v => AffineSpace p v | p -> v where
-- (.-.) :: p s -> p s -> v s
-- (.+^) :: p s -> v s -> p s
--
-- Perhaps with constraints on s. We couldn't then define instances for
-- doubles & floats.
-- | Point minus vector
(.-^) :: (Num s, AffineSpace p v s) => p -> v -> p
p .-^ v = p .+^ negateV v
-- | Square of the distance between two points. Sometimes useful for
-- efficiency. See also 'distance'.
distanceSq :: (AffineSpace p v s, InnerSpace v s) => p -> p -> s
distanceSq = (fmap.fmap) magnitudeSq (.-.)
-- | Distance between two points. See also 'distanceSq'.
distance :: (Floating s, AffineSpace p v s, InnerSpace v s) => p -> p -> s
distance = (fmap.fmap) sqrt distanceSq
-- | Affine linear interpolation. Varies from @p@ to @p'@ as @s@ varies
-- from 0 to 1. See also 'lerp' (on vector spaces).
alerp :: AffineSpace p v s => p -> p -> s -> p
alerp p p' s = p .+^ (s *^ (p' .-. p))
instance AffineSpace Double Double Double where
(.-.) = (-)
(.+^) = (+)
instance AffineSpace Float Float Float where
(.-.) = (-)
(.+^) = (+)