--------------------------------------------------------------------------------
-- |
-- Module      :  Data.Geometry.Duality
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--------------------------------------------------------------------------------
module Data.Geometry.Duality where

import Data.Geometry.Line
import Data.Geometry.Point
import Data.Maybe(fromJust)
--------------------------------------------------------------------------------
-- * Standard Point-Line duality in R^2

-- | Maps a line point (px,py) to a line (y=px*x - py)
dualLine              :: Num r => Point 2 r -> Line 2 r
dualLine :: Point 2 r -> Line 2 r
dualLine (Point2 r
x r
y) = r -> r -> Line 2 r
forall r. Num r => r -> r -> Line 2 r
fromLinearFunction r
x (-r
y)

-- | Returns Nothing if the input line is vertical
-- Maps a line l: y = ax + b to a point (a,-b)
dualPoint   :: (Fractional r, Eq r) => Line 2 r -> Maybe (Point 2 r)
dualPoint :: Line 2 r -> Maybe (Point 2 r)
dualPoint Line 2 r
l = (\(r
a,r
b) -> r -> r -> Point 2 r
forall r. r -> r -> Point 2 r
Point2 r
a (-r
b)) ((r, r) -> Point 2 r) -> Maybe (r, r) -> Maybe (Point 2 r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Line 2 r -> Maybe (r, r)
forall r. (Fractional r, Eq r) => Line 2 r -> Maybe (r, r)
toLinearFunction Line 2 r
l

-- | Pre: the input line is not vertical
dualPoint' :: (Fractional r, Eq r) => Line 2 r -> Point 2 r
dualPoint' :: Line 2 r -> Point 2 r
dualPoint' = Maybe (Point 2 r) -> Point 2 r
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Point 2 r) -> Point 2 r)
-> (Line 2 r -> Maybe (Point 2 r)) -> Line 2 r -> Point 2 r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Line 2 r -> Maybe (Point 2 r)
forall r. (Fractional r, Eq r) => Line 2 r -> Maybe (Point 2 r)
dualPoint