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

import Control.Lens (iso,Iso)
import Data.Geometry.Properties
import Data.Geometry.Transformation

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

-- | The boundary of a geometric object.
newtype Boundary g = Boundary g
                   deriving (Int -> Boundary g -> ShowS
[Boundary g] -> ShowS
Boundary g -> String
(Int -> Boundary g -> ShowS)
-> (Boundary g -> String)
-> ([Boundary g] -> ShowS)
-> Show (Boundary g)
forall g. Show g => Int -> Boundary g -> ShowS
forall g. Show g => [Boundary g] -> ShowS
forall g. Show g => Boundary g -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Boundary g] -> ShowS
$cshowList :: forall g. Show g => [Boundary g] -> ShowS
show :: Boundary g -> String
$cshow :: forall g. Show g => Boundary g -> String
showsPrec :: Int -> Boundary g -> ShowS
$cshowsPrec :: forall g. Show g => Int -> Boundary g -> ShowS
Show,Boundary g -> Boundary g -> Bool
(Boundary g -> Boundary g -> Bool)
-> (Boundary g -> Boundary g -> Bool) -> Eq (Boundary g)
forall g. Eq g => Boundary g -> Boundary g -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Boundary g -> Boundary g -> Bool
$c/= :: forall g. Eq g => Boundary g -> Boundary g -> Bool
== :: Boundary g -> Boundary g -> Bool
$c== :: forall g. Eq g => Boundary g -> Boundary g -> Bool
Eq,Eq (Boundary g)
Eq (Boundary g)
-> (Boundary g -> Boundary g -> Ordering)
-> (Boundary g -> Boundary g -> Bool)
-> (Boundary g -> Boundary g -> Bool)
-> (Boundary g -> Boundary g -> Bool)
-> (Boundary g -> Boundary g -> Bool)
-> (Boundary g -> Boundary g -> Boundary g)
-> (Boundary g -> Boundary g -> Boundary g)
-> Ord (Boundary g)
Boundary g -> Boundary g -> Bool
Boundary g -> Boundary g -> Ordering
Boundary g -> Boundary g -> Boundary g
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall g. Ord g => Eq (Boundary g)
forall g. Ord g => Boundary g -> Boundary g -> Bool
forall g. Ord g => Boundary g -> Boundary g -> Ordering
forall g. Ord g => Boundary g -> Boundary g -> Boundary g
min :: Boundary g -> Boundary g -> Boundary g
$cmin :: forall g. Ord g => Boundary g -> Boundary g -> Boundary g
max :: Boundary g -> Boundary g -> Boundary g
$cmax :: forall g. Ord g => Boundary g -> Boundary g -> Boundary g
>= :: Boundary g -> Boundary g -> Bool
$c>= :: forall g. Ord g => Boundary g -> Boundary g -> Bool
> :: Boundary g -> Boundary g -> Bool
$c> :: forall g. Ord g => Boundary g -> Boundary g -> Bool
<= :: Boundary g -> Boundary g -> Bool
$c<= :: forall g. Ord g => Boundary g -> Boundary g -> Bool
< :: Boundary g -> Boundary g -> Bool
$c< :: forall g. Ord g => Boundary g -> Boundary g -> Bool
compare :: Boundary g -> Boundary g -> Ordering
$ccompare :: forall g. Ord g => Boundary g -> Boundary g -> Ordering
$cp1Ord :: forall g. Ord g => Eq (Boundary g)
Ord,ReadPrec [Boundary g]
ReadPrec (Boundary g)
Int -> ReadS (Boundary g)
ReadS [Boundary g]
(Int -> ReadS (Boundary g))
-> ReadS [Boundary g]
-> ReadPrec (Boundary g)
-> ReadPrec [Boundary g]
-> Read (Boundary g)
forall g. Read g => ReadPrec [Boundary g]
forall g. Read g => ReadPrec (Boundary g)
forall g. Read g => Int -> ReadS (Boundary g)
forall g. Read g => ReadS [Boundary g]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Boundary g]
$creadListPrec :: forall g. Read g => ReadPrec [Boundary g]
readPrec :: ReadPrec (Boundary g)
$creadPrec :: forall g. Read g => ReadPrec (Boundary g)
readList :: ReadS [Boundary g]
$creadList :: forall g. Read g => ReadS [Boundary g]
readsPrec :: Int -> ReadS (Boundary g)
$creadsPrec :: forall g. Read g => Int -> ReadS (Boundary g)
Read,Transformation (Dimension (Boundary g)) (NumType (Boundary g))
-> Boundary g -> Boundary g
(Transformation (Dimension (Boundary g)) (NumType (Boundary g))
 -> Boundary g -> Boundary g)
-> IsTransformable (Boundary g)
forall g.
IsTransformable g =>
Transformation (Dimension (Boundary g)) (NumType (Boundary g))
-> Boundary g -> Boundary g
forall g.
(Transformation (Dimension g) (NumType g) -> g -> g)
-> IsTransformable g
transformBy :: Transformation (Dimension (Boundary g)) (NumType (Boundary g))
-> Boundary g -> Boundary g
$ctransformBy :: forall g.
IsTransformable g =>
Transformation (Dimension (Boundary g)) (NumType (Boundary g))
-> Boundary g -> Boundary g
IsTransformable
                            ,a -> Boundary b -> Boundary a
(a -> b) -> Boundary a -> Boundary b
(forall a b. (a -> b) -> Boundary a -> Boundary b)
-> (forall a b. a -> Boundary b -> Boundary a) -> Functor Boundary
forall a b. a -> Boundary b -> Boundary a
forall a b. (a -> b) -> Boundary a -> Boundary b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Boundary b -> Boundary a
$c<$ :: forall a b. a -> Boundary b -> Boundary a
fmap :: (a -> b) -> Boundary a -> Boundary b
$cfmap :: forall a b. (a -> b) -> Boundary a -> Boundary b
Functor,Boundary a -> Bool
(a -> m) -> Boundary a -> m
(a -> b -> b) -> b -> Boundary a -> b
(forall m. Monoid m => Boundary m -> m)
-> (forall m a. Monoid m => (a -> m) -> Boundary a -> m)
-> (forall m a. Monoid m => (a -> m) -> Boundary a -> m)
-> (forall a b. (a -> b -> b) -> b -> Boundary a -> b)
-> (forall a b. (a -> b -> b) -> b -> Boundary a -> b)
-> (forall b a. (b -> a -> b) -> b -> Boundary a -> b)
-> (forall b a. (b -> a -> b) -> b -> Boundary a -> b)
-> (forall a. (a -> a -> a) -> Boundary a -> a)
-> (forall a. (a -> a -> a) -> Boundary a -> a)
-> (forall a. Boundary a -> [a])
-> (forall a. Boundary a -> Bool)
-> (forall a. Boundary a -> Int)
-> (forall a. Eq a => a -> Boundary a -> Bool)
-> (forall a. Ord a => Boundary a -> a)
-> (forall a. Ord a => Boundary a -> a)
-> (forall a. Num a => Boundary a -> a)
-> (forall a. Num a => Boundary a -> a)
-> Foldable Boundary
forall a. Eq a => a -> Boundary a -> Bool
forall a. Num a => Boundary a -> a
forall a. Ord a => Boundary a -> a
forall m. Monoid m => Boundary m -> m
forall a. Boundary a -> Bool
forall a. Boundary a -> Int
forall a. Boundary a -> [a]
forall a. (a -> a -> a) -> Boundary a -> a
forall m a. Monoid m => (a -> m) -> Boundary a -> m
forall b a. (b -> a -> b) -> b -> Boundary a -> b
forall a b. (a -> b -> b) -> b -> Boundary a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Boundary a -> a
$cproduct :: forall a. Num a => Boundary a -> a
sum :: Boundary a -> a
$csum :: forall a. Num a => Boundary a -> a
minimum :: Boundary a -> a
$cminimum :: forall a. Ord a => Boundary a -> a
maximum :: Boundary a -> a
$cmaximum :: forall a. Ord a => Boundary a -> a
elem :: a -> Boundary a -> Bool
$celem :: forall a. Eq a => a -> Boundary a -> Bool
length :: Boundary a -> Int
$clength :: forall a. Boundary a -> Int
null :: Boundary a -> Bool
$cnull :: forall a. Boundary a -> Bool
toList :: Boundary a -> [a]
$ctoList :: forall a. Boundary a -> [a]
foldl1 :: (a -> a -> a) -> Boundary a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Boundary a -> a
foldr1 :: (a -> a -> a) -> Boundary a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Boundary a -> a
foldl' :: (b -> a -> b) -> b -> Boundary a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Boundary a -> b
foldl :: (b -> a -> b) -> b -> Boundary a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Boundary a -> b
foldr' :: (a -> b -> b) -> b -> Boundary a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Boundary a -> b
foldr :: (a -> b -> b) -> b -> Boundary a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Boundary a -> b
foldMap' :: (a -> m) -> Boundary a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Boundary a -> m
foldMap :: (a -> m) -> Boundary a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Boundary a -> m
fold :: Boundary m -> m
$cfold :: forall m. Monoid m => Boundary m -> m
Foldable,Functor Boundary
Foldable Boundary
Functor Boundary
-> Foldable Boundary
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Boundary a -> f (Boundary b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Boundary (f a) -> f (Boundary a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Boundary a -> m (Boundary b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Boundary (m a) -> m (Boundary a))
-> Traversable Boundary
(a -> f b) -> Boundary a -> f (Boundary b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Boundary (m a) -> m (Boundary a)
forall (f :: * -> *) a.
Applicative f =>
Boundary (f a) -> f (Boundary a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Boundary a -> m (Boundary b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Boundary a -> f (Boundary b)
sequence :: Boundary (m a) -> m (Boundary a)
$csequence :: forall (m :: * -> *) a. Monad m => Boundary (m a) -> m (Boundary a)
mapM :: (a -> m b) -> Boundary a -> m (Boundary b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Boundary a -> m (Boundary b)
sequenceA :: Boundary (f a) -> f (Boundary a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Boundary (f a) -> f (Boundary a)
traverse :: (a -> f b) -> Boundary a -> f (Boundary b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Boundary a -> f (Boundary b)
$cp2Traversable :: Foldable Boundary
$cp1Traversable :: Functor Boundary
Traversable)

type instance NumType (Boundary g)   = NumType g
type instance Dimension (Boundary g) = Dimension g

-- | Iso for converting between things with a boundary and without its boundary
_Boundary :: Iso g h (Boundary g) (Boundary h)
_Boundary :: p (Boundary g) (f (Boundary h)) -> p g (f h)
_Boundary = (g -> Boundary g)
-> (Boundary h -> h) -> Iso g h (Boundary g) (Boundary h)
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso g -> Boundary g
forall g. g -> Boundary g
Boundary (\(Boundary h
b) -> h
b)


-- | Result of a query that asks if something is Inside a g, *on* the boundary
-- of the g, or outside.
data PointLocationResult = Inside | OnBoundary | Outside deriving (Int -> PointLocationResult -> ShowS
[PointLocationResult] -> ShowS
PointLocationResult -> String
(Int -> PointLocationResult -> ShowS)
-> (PointLocationResult -> String)
-> ([PointLocationResult] -> ShowS)
-> Show PointLocationResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PointLocationResult] -> ShowS
$cshowList :: [PointLocationResult] -> ShowS
show :: PointLocationResult -> String
$cshow :: PointLocationResult -> String
showsPrec :: Int -> PointLocationResult -> ShowS
$cshowsPrec :: Int -> PointLocationResult -> ShowS
Show,ReadPrec [PointLocationResult]
ReadPrec PointLocationResult
Int -> ReadS PointLocationResult
ReadS [PointLocationResult]
(Int -> ReadS PointLocationResult)
-> ReadS [PointLocationResult]
-> ReadPrec PointLocationResult
-> ReadPrec [PointLocationResult]
-> Read PointLocationResult
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PointLocationResult]
$creadListPrec :: ReadPrec [PointLocationResult]
readPrec :: ReadPrec PointLocationResult
$creadPrec :: ReadPrec PointLocationResult
readList :: ReadS [PointLocationResult]
$creadList :: ReadS [PointLocationResult]
readsPrec :: Int -> ReadS PointLocationResult
$creadsPrec :: Int -> ReadS PointLocationResult
Read,PointLocationResult -> PointLocationResult -> Bool
(PointLocationResult -> PointLocationResult -> Bool)
-> (PointLocationResult -> PointLocationResult -> Bool)
-> Eq PointLocationResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PointLocationResult -> PointLocationResult -> Bool
$c/= :: PointLocationResult -> PointLocationResult -> Bool
== :: PointLocationResult -> PointLocationResult -> Bool
$c== :: PointLocationResult -> PointLocationResult -> Bool
Eq)