module Data.Geo.Jord.Triangle
( Triangle
, vertex0
, vertex1
, vertex2
, make
, unsafeMake
, centroid
, circumcentre
, contains
) where
import Control.Monad (join)
import Data.Maybe (fromJust)
import Data.Geo.Jord.Geodetic (HorizontalPosition)
import qualified Data.Geo.Jord.Geodetic as Geodetic
import qualified Data.Geo.Jord.GreatCircle as GreatCircle
import qualified Data.Geo.Jord.Math3d as Math3d
import Data.Geo.Jord.Model (Spherical)
data Triangle a =
Triangle (HorizontalPosition a) (HorizontalPosition a) (HorizontalPosition a)
deriving (Eq, Show)
vertex0 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex0 (Triangle v _ _) = v
vertex1 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex1 (Triangle _ v _) = v
vertex2 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex2 (Triangle _ _ v) = v
make ::
(Spherical a)
=> HorizontalPosition a
-> HorizontalPosition a
-> HorizontalPosition a
-> Maybe (Triangle a)
make v0 v1 v2
| v0 == v1 || v1 == v2 || v2 == v0 = Nothing
| a0 == v1 || a0 == v2 || a1 == v2 = Nothing
| otherwise = Just (Triangle v0 v1 v2)
where
a0 = Geodetic.antipode v0
a1 = Geodetic.antipode v1
unsafeMake ::
(Spherical a)
=> HorizontalPosition a
-> HorizontalPosition a
-> HorizontalPosition a
-> Triangle a
unsafeMake = Triangle
contains :: (Spherical a) => Triangle a -> HorizontalPosition a -> Bool
contains (Triangle v0 v1 v2) p = GreatCircle.enclosedBy p [v0, v1, v2]
centroid :: (Spherical a) => Triangle a -> HorizontalPosition a
centroid (Triangle v0 v1 v2) = fromJust c
where
m1 = GreatCircle.mean [v1, v2] >>= GreatCircle.minorArc v0
m2 = GreatCircle.mean [v2, v0] >>= GreatCircle.minorArc v1
c = join (GreatCircle.intersection <$> m1 <*> m2)
circumcentre :: (Spherical a) => Triangle a -> HorizontalPosition a
circumcentre (Triangle v0 v1 v2) = Geodetic.nvectorPos' cu (Geodetic.model v0)
where
e0 = Math3d.subtract (Geodetic.nvector v1) (Geodetic.nvector v0)
e1 = Math3d.subtract (Geodetic.nvector v2) (Geodetic.nvector v0)
cu = Math3d.cross e0 e1