module Data.Geometry.Point.Orientation where

import Algorithms.Geometry.SoS.Orientation
import Algorithms.Geometry.SoS.Sign
import Data.Ext
import Data.Geometry.Point.Internal
import Data.Geometry.Vector

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

newtype StrictCCW = SCCW Sign deriving StrictCCW -> StrictCCW -> Bool
(StrictCCW -> StrictCCW -> Bool)
-> (StrictCCW -> StrictCCW -> Bool) -> Eq StrictCCW
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StrictCCW -> StrictCCW -> Bool
$c/= :: StrictCCW -> StrictCCW -> Bool
== :: StrictCCW -> StrictCCW -> Bool
$c== :: StrictCCW -> StrictCCW -> Bool
Eq

pattern CCW :: StrictCCW
pattern $bCCW :: StrictCCW
$mCCW :: forall r. StrictCCW -> (Void# -> r) -> (Void# -> r) -> r
CCW = SCCW Negative

pattern CW  :: StrictCCW
pattern $bCW :: StrictCCW
$mCW :: forall r. StrictCCW -> (Void# -> r) -> (Void# -> r) -> r
CW  = SCCW Positive
{-# COMPLETE CCW, CW #-}

instance Show StrictCCW where
  show :: StrictCCW -> String
show = \case
    StrictCCW
CCW -> String
"CCW"
    StrictCCW
CW  -> String
"CW"


-- | Given three points p q and r determine the orientation when going from p to r via q.
ccw       :: (Ord r, Num r, Ord i)
          => Point 2 r :+ i -> Point 2 r :+ i -> Point 2 r :+ i -> StrictCCW
ccw :: (Point 2 r :+ i)
-> (Point 2 r :+ i) -> (Point 2 r :+ i) -> StrictCCW
ccw Point 2 r :+ i
p Point 2 r :+ i
q Point 2 r :+ i
r = Sign -> StrictCCW
SCCW (Sign -> StrictCCW) -> Sign -> StrictCCW
forall a b. (a -> b) -> a -> b
$ (Point 2 r :+ i) -> Vector 2 (Point 2 r :+ i) -> Sign
forall (d :: Nat) r i.
(SoS d, Num r, Ord r, Ord i) =>
(Point d r :+ i) -> Vector d (Point d r :+ i) -> Sign
sideTest Point 2 r :+ i
r ((Point 2 r :+ i) -> (Point 2 r :+ i) -> Vector 2 (Point 2 r :+ i)
forall r. r -> r -> Vector 2 r
Vector2 Point 2 r :+ i
p Point 2 r :+ i
q)