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 (Triangle a -> Triangle a -> Bool
(Triangle a -> Triangle a -> Bool)
-> (Triangle a -> Triangle a -> Bool) -> Eq (Triangle a)
forall a. Model a => Triangle a -> Triangle a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Triangle a -> Triangle a -> Bool
$c/= :: forall a. Model a => Triangle a -> Triangle a -> Bool
== :: Triangle a -> Triangle a -> Bool
$c== :: forall a. Model a => Triangle a -> Triangle a -> Bool
Eq, Int -> Triangle a -> ShowS
[Triangle a] -> ShowS
Triangle a -> String
(Int -> Triangle a -> ShowS)
-> (Triangle a -> String)
-> ([Triangle a] -> ShowS)
-> Show (Triangle a)
forall a. Model a => Int -> Triangle a -> ShowS
forall a. Model a => [Triangle a] -> ShowS
forall a. Model a => Triangle a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Triangle a] -> ShowS
$cshowList :: forall a. Model a => [Triangle a] -> ShowS
show :: Triangle a -> String
$cshow :: forall a. Model a => Triangle a -> String
showsPrec :: Int -> Triangle a -> ShowS
$cshowsPrec :: forall a. Model a => Int -> Triangle a -> ShowS
Show)
vertex0 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex0 :: Triangle a -> HorizontalPosition a
vertex0 (Triangle HorizontalPosition a
v HorizontalPosition a
_ HorizontalPosition a
_) = HorizontalPosition a
v
vertex1 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex1 :: Triangle a -> HorizontalPosition a
vertex1 (Triangle HorizontalPosition a
_ HorizontalPosition a
v HorizontalPosition a
_) = HorizontalPosition a
v
vertex2 :: (Spherical a) => Triangle a -> HorizontalPosition a
vertex2 :: Triangle a -> HorizontalPosition a
vertex2 (Triangle HorizontalPosition a
_ HorizontalPosition a
_ HorizontalPosition a
v) = HorizontalPosition a
v
make ::
(Spherical a)
=> HorizontalPosition a
-> HorizontalPosition a
-> HorizontalPosition a
-> Maybe (Triangle a)
make :: HorizontalPosition a
-> HorizontalPosition a
-> HorizontalPosition a
-> Maybe (Triangle a)
make HorizontalPosition a
v0 HorizontalPosition a
v1 HorizontalPosition a
v2
| HorizontalPosition a
v0 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v1 Bool -> Bool -> Bool
|| HorizontalPosition a
v1 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v2 Bool -> Bool -> Bool
|| HorizontalPosition a
v2 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v0 = Maybe (Triangle a)
forall a. Maybe a
Nothing
| HorizontalPosition a
a0 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v1 Bool -> Bool -> Bool
|| HorizontalPosition a
a0 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v2 Bool -> Bool -> Bool
|| HorizontalPosition a
a1 HorizontalPosition a -> HorizontalPosition a -> Bool
forall a. Eq a => a -> a -> Bool
== HorizontalPosition a
v2 = Maybe (Triangle a)
forall a. Maybe a
Nothing
| Bool
otherwise = Triangle a -> Maybe (Triangle a)
forall a. a -> Maybe a
Just (HorizontalPosition a
-> HorizontalPosition a -> HorizontalPosition a -> Triangle a
forall a.
HorizontalPosition a
-> HorizontalPosition a -> HorizontalPosition a -> Triangle a
Triangle HorizontalPosition a
v0 HorizontalPosition a
v1 HorizontalPosition a
v2)
where
a0 :: HorizontalPosition a
a0 = HorizontalPosition a -> HorizontalPosition a
forall a. Model a => HorizontalPosition a -> HorizontalPosition a
Geodetic.antipode HorizontalPosition a
v0
a1 :: HorizontalPosition a
a1 = HorizontalPosition a -> HorizontalPosition a
forall a. Model a => HorizontalPosition a -> HorizontalPosition a
Geodetic.antipode HorizontalPosition a
v1
unsafeMake ::
(Spherical a)
=> HorizontalPosition a
-> HorizontalPosition a
-> HorizontalPosition a
-> Triangle a
unsafeMake :: HorizontalPosition a
-> HorizontalPosition a -> HorizontalPosition a -> Triangle a
unsafeMake = HorizontalPosition a
-> HorizontalPosition a -> HorizontalPosition a -> Triangle a
forall a.
HorizontalPosition a
-> HorizontalPosition a -> HorizontalPosition a -> Triangle a
Triangle
contains :: (Spherical a) => Triangle a -> HorizontalPosition a -> Bool
contains :: Triangle a -> HorizontalPosition a -> Bool
contains (Triangle HorizontalPosition a
v0 HorizontalPosition a
v1 HorizontalPosition a
v2) HorizontalPosition a
p = HorizontalPosition a -> [HorizontalPosition a] -> Bool
forall a.
Spherical a =>
HorizontalPosition a -> [HorizontalPosition a] -> Bool
GreatCircle.enclosedBy HorizontalPosition a
p [HorizontalPosition a
v0, HorizontalPosition a
v1, HorizontalPosition a
v2]
centroid :: (Spherical a) => Triangle a -> HorizontalPosition a
centroid :: Triangle a -> HorizontalPosition a
centroid (Triangle HorizontalPosition a
v0 HorizontalPosition a
v1 HorizontalPosition a
v2) = Maybe (HorizontalPosition a) -> HorizontalPosition a
forall a. HasCallStack => Maybe a -> a
fromJust Maybe (HorizontalPosition a)
c
where
m1 :: Maybe (MinorArc a)
m1 = [HorizontalPosition a] -> Maybe (HorizontalPosition a)
forall a.
Spherical a =>
[HorizontalPosition a] -> Maybe (HorizontalPosition a)
GreatCircle.mean [HorizontalPosition a
v1, HorizontalPosition a
v2] Maybe (HorizontalPosition a)
-> (HorizontalPosition a -> Maybe (MinorArc a))
-> Maybe (MinorArc a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HorizontalPosition a -> HorizontalPosition a -> Maybe (MinorArc a)
forall a.
Spherical a =>
HorizontalPosition a -> HorizontalPosition a -> Maybe (MinorArc a)
GreatCircle.minorArc HorizontalPosition a
v0
m2 :: Maybe (MinorArc a)
m2 = [HorizontalPosition a] -> Maybe (HorizontalPosition a)
forall a.
Spherical a =>
[HorizontalPosition a] -> Maybe (HorizontalPosition a)
GreatCircle.mean [HorizontalPosition a
v2, HorizontalPosition a
v0] Maybe (HorizontalPosition a)
-> (HorizontalPosition a -> Maybe (MinorArc a))
-> Maybe (MinorArc a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HorizontalPosition a -> HorizontalPosition a -> Maybe (MinorArc a)
forall a.
Spherical a =>
HorizontalPosition a -> HorizontalPosition a -> Maybe (MinorArc a)
GreatCircle.minorArc HorizontalPosition a
v1
c :: Maybe (HorizontalPosition a)
c = Maybe (Maybe (HorizontalPosition a))
-> Maybe (HorizontalPosition a)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (MinorArc a -> MinorArc a -> Maybe (HorizontalPosition a)
forall a.
Spherical a =>
MinorArc a -> MinorArc a -> Maybe (HorizontalPosition a)
GreatCircle.intersection (MinorArc a -> MinorArc a -> Maybe (HorizontalPosition a))
-> Maybe (MinorArc a)
-> Maybe (MinorArc a -> Maybe (HorizontalPosition a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (MinorArc a)
m1 Maybe (MinorArc a -> Maybe (HorizontalPosition a))
-> Maybe (MinorArc a) -> Maybe (Maybe (HorizontalPosition a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (MinorArc a)
m2)
circumcentre :: (Spherical a) => Triangle a -> HorizontalPosition a
circumcentre :: Triangle a -> HorizontalPosition a
circumcentre (Triangle HorizontalPosition a
v0 HorizontalPosition a
v1 HorizontalPosition a
v2) = V3 -> a -> HorizontalPosition a
forall a. Model a => V3 -> a -> HorizontalPosition a
Geodetic.nvectorPos' V3
cu (HorizontalPosition a -> a
forall a. Model a => HorizontalPosition a -> a
Geodetic.model HorizontalPosition a
v0)
where
e0 :: V3
e0 = V3 -> V3 -> V3
Math3d.subtract (HorizontalPosition a -> V3
forall a. HasCoordinates a => a -> V3
Geodetic.nvector HorizontalPosition a
v1) (HorizontalPosition a -> V3
forall a. HasCoordinates a => a -> V3
Geodetic.nvector HorizontalPosition a
v0)
e1 :: V3
e1 = V3 -> V3 -> V3
Math3d.subtract (HorizontalPosition a -> V3
forall a. HasCoordinates a => a -> V3
Geodetic.nvector HorizontalPosition a
v2) (HorizontalPosition a -> V3
forall a. HasCoordinates a => a -> V3
Geodetic.nvector HorizontalPosition a
v0)
cu :: V3
cu = V3 -> V3 -> V3
Math3d.cross V3
e0 V3
e1