module Geom2d.Point
( Point (..)
, Point'
, Triangle
, Scale (..)
, normalize
, magnitude
, dot
, cross
, triArea
, pointInTriangle
)
where
import Geom2d.Point.Internal
type Triangle p = (p,p,p)
infixl 7 `dot`,`cross`
dot :: (Num a, Point p) => p a -> p a -> a
dot a b = x a * x b + y a * y b
cross :: (Num a, Point p) => p a -> p a -> a
cross a b = x a * y b y a * x b
triArea :: (Point p, Num (p a), Fractional a) => Triangle (p a) -> a
triArea (a,b,c) = abs $ ((b a) `cross` (c a)) / 2
pointInTriangle :: (Eq (p a), Num (p a), Fractional a, Point p, Ord a) =>
Triangle (p a) -> p a -> Bool
pointInTriangle (a,b,c) p
| b == a || c == a || b == c = False
| p == a = True
| otherwise = u >= 0 && v >= 0 && u + v <= 1
where
u = ( v1Square * v2v0 v1v0 * v2v1 ) / denom
v = ( v0Square * v2v1 v0v1 * v2v0 ) / denom
denom = v0Square * v1Square v0v1 * v1v0
v1Square = v1 `dot` v1
v0Square = v0 `dot` v0
v1v0 = v1 `dot` v0
v0v1 = v0 `dot` v1
v2v0 = v2 `dot` v0
v2v1 = v2 `dot` v1
v0 = ca
v1 = ba
v2 = pa
class Scale p where
scale :: (Num a) => a -> p a -> p a
instance Scale Point' where
scale s (Point' (a,b)) = Point' (a * s, b * s)
normalize :: (Scale p, Point p, Fractional a, Eq a, Floating a) =>
p a -> Maybe (p a)
normalize v | magnitude v == 0 = Nothing
| otherwise = Just $ scale (1/magnitude v) v