module GeomAlg.Triangle where
import GeomAlg.Point ( Point )
import GeomAlg.Point2 ( Point2, area2, orientation, Orientation (Collinear) )
import GeomAlg.Point3 ( Point3 )
import GeomAlg.Line ( Line (Segment) )
import GeomAlg.Circle ( circleFrom3Points )
import qualified GeomAlg.Circle as C (Circle (center))
import Maybe ( fromJust )
import GeomAlg.External.Utilities ( Rel3 )
newtype (Point p, Num a) => Triangle p a
= Triangle (p a, p a, p a)
type Triangle2 a = Triangle Point2 a
type Triangle3 a = Triangle Point3 a
vertices :: (Num a, Point p) => Triangle p a -> [p a]
vertices (Triangle (p,q,r)) = [p,q,r]
segments :: (Num a, Point p) => Triangle p a -> [Line p a]
segments (Triangle (p,q,r)) = [Segment p q, Segment q r, Segment r p]
area :: Fractional a => Triangle Point2 a -> a
area (Triangle (p,q,r)) = 0.5 * area2 p q r
contains, containsBNV :: (Num a, Ord a) => Triangle Point2 a -> Point2 a -> Bool
contains tri@(Triangle (s,t,v)) p = containsBNV tri p || p==s || p==t || p==v
containsBNV tri p = checkBy test tri p
where test Collinear b c = b==c
test a Collinear c = a==c
test a b Collinear = a==b
test a b c = a==b && b==c
inInteriourOf :: (Num a, Ord a) => Point2 a -> Triangle Point2 a -> Bool
inInteriourOf p tri = checkBy test tri p
where test Collinear b c = False
test a Collinear c = False
test a b Collinear = False
test a b c = a==b && b==c
checkBy :: (Num a, Ord a) => Rel3 Orientation -> Triangle2 a -> Point2 a -> Bool
checkBy chk (Triangle (s,t,v)) p = chk a b c
where a = orientation s t p
b = orientation t v p
c = orientation v s p
center :: Fractional a => Triangle2 a -> Point2 a
center (Triangle (p, q, r)) = C.center (fromJust (circleFrom3Points p q r))