module GeomAlg.Point (
Point (..),
toList,
xcoord, ycoord, zcoord,
lexic,
lessIth, leqIth, equalIth, geqIth, greaterIth,
compareIthBy, compareIth,
inIntervalIth, inInterval,
norm, distance, sqrDistance
) where
import GeomAlg.External.Utilities (Rel, OrderRel)
infixl 7 <.>
infixl 6 <*>
infixl 5 <+>, <->
infix 4 <==>, </=>
class Functor p => Point p where
origin :: Num a => p a
dimension :: Num a => p a -> Int
ith :: Num a => Int -> p a -> a
(<==>) :: Num a => p a -> p a -> Bool
(</=>) :: Num a => p a -> p a -> Bool
x </=> y = not (x <==> y)
(<+>) :: Num a => p a -> p a -> p a
(<->) :: Num a => p a -> p a -> p a
v <-> w = v <+> negateP w
negateP :: Num a => p a -> p a
negateP = fmap (0)
(<.>) :: Num a => p a -> p a -> a
(<*>) :: Num a => a -> p a -> p a
k <*> p = fmap (k*) p
toList :: (Point p, Num a) => p a -> [a]
toList p = [ ith i p | i <- [1..dimension p]]
xcoord :: (Num a, Point p) => p a -> a
xcoord = ith 1
ycoord :: (Num a, Point p) => p a -> a
ycoord = ith 2
zcoord :: (Num a, Point p) => p a -> a
zcoord = ith 3
lexic :: (Point p, Num a, Ord a) => OrderRel (p a)
p `lexic` q = case is of
[] -> EQ
(i:_) -> compareIth i p q
where is = dropWhile (\ i -> equalIth i p q) [1..dimension p]
cmpAux :: (Point p, Num a) => Rel a -> Int -> Rel (p a)
cmpAux rel i x y = ith i x `rel` ith i y
lessIth :: (Point p, Ord a, Num a) => Int -> Rel (p a)
lessIth = cmpAux (<)
leqIth :: (Point p, Ord a, Num a) => Int -> Rel (p a)
leqIth = cmpAux (<=)
equalIth :: (Point p, Ord a, Num a) => Int -> Rel (p a)
equalIth = cmpAux (==)
geqIth :: (Point p, Ord a, Num a) => Int -> Rel (p a)
geqIth = cmpAux (>=)
greaterIth :: (Point p, Ord a, Num a) => Int -> Rel (p a)
greaterIth = cmpAux (>)
compareIthBy :: (Num a, Point p) => OrderRel a -> Int -> OrderRel (p a)
compareIthBy cmp i x y = cmp (ith i x) (ith i y)
compareIth :: (Ord a, Num a, Point p) => Int -> OrderRel (p a)
compareIth = compareIthBy compare
inIntervalIth :: (Point p, Num a, Ord a) => Int -> p a -> (p a,p a) -> Bool
inIntervalIth i x (p,q) = ith i p <= y && y <= ith i q
where y = ith i x
inInterval :: (Point p, Num a, Ord a) => p a -> (p a,p a) -> Bool
x `inInterval` (p,q) = all (\ i -> inIntervalIth i x (p,q)) [1..dimension x]
norm :: (Point p, Floating a) => p a -> a
norm x = sqrt (x <.> x)
distance :: (Point p, Floating a) => p a -> p a -> a
distance p q = norm (p <-> q)
sqrDistance :: (Point p, Num a) => p a -> p a -> a
sqrDistance p q = r <.> r where r = p <-> q