--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.Box.Sides
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--------------------------------------------------------------------------------
module HGeometry.Box.Sides
  ( Sides(Sides), north, east, south, west
  , topSide, bottomSide, leftSide, rightSide
  , sides, sides'

  , sideDirections
  , sideValues
  , intersectingHalfPlanes
  ) where

import Control.Lens hiding ((<.>))
import Data.Foldable1
import Data.Functor.Apply
import GHC.Generics (Generic)
import HGeometry.Box.Class
import HGeometry.Box.Corners
import HGeometry.Direction
import HGeometry.HalfSpace
import HGeometry.Line.PointAndVector
import HGeometry.LineSegment
import HGeometry.Point
import HGeometry.Vector

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

-- | The four sides of a rectangle
--
-- i.e. a `Sides n e s w` rerpesents an object whose north side is n, east side e, south
-- side s, and west side w.
data Sides a = Sides { forall a. Sides a -> a
_north :: !a
                     , forall a. Sides a -> a
_east  :: !a
                     , forall a. Sides a -> a
_south :: !a
                     , forall a. Sides a -> a
_west  :: !a
                     }
             deriving stock (Int -> Sides a -> ShowS
[Sides a] -> ShowS
Sides a -> String
(Int -> Sides a -> ShowS)
-> (Sides a -> String) -> ([Sides a] -> ShowS) -> Show (Sides a)
forall a. Show a => Int -> Sides a -> ShowS
forall a. Show a => [Sides a] -> ShowS
forall a. Show a => Sides a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Sides a -> ShowS
showsPrec :: Int -> Sides a -> ShowS
$cshow :: forall a. Show a => Sides a -> String
show :: Sides a -> String
$cshowList :: forall a. Show a => [Sides a] -> ShowS
showList :: [Sides a] -> ShowS
Show,ReadPrec [Sides a]
ReadPrec (Sides a)
Int -> ReadS (Sides a)
ReadS [Sides a]
(Int -> ReadS (Sides a))
-> ReadS [Sides a]
-> ReadPrec (Sides a)
-> ReadPrec [Sides a]
-> Read (Sides a)
forall a. Read a => ReadPrec [Sides a]
forall a. Read a => ReadPrec (Sides a)
forall a. Read a => Int -> ReadS (Sides a)
forall a. Read a => ReadS [Sides a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Sides a)
readsPrec :: Int -> ReadS (Sides a)
$creadList :: forall a. Read a => ReadS [Sides a]
readList :: ReadS [Sides a]
$creadPrec :: forall a. Read a => ReadPrec (Sides a)
readPrec :: ReadPrec (Sides a)
$creadListPrec :: forall a. Read a => ReadPrec [Sides a]
readListPrec :: ReadPrec [Sides a]
Read,Sides a -> Sides a -> Bool
(Sides a -> Sides a -> Bool)
-> (Sides a -> Sides a -> Bool) -> Eq (Sides a)
forall a. Eq a => Sides a -> Sides a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Sides a -> Sides a -> Bool
== :: Sides a -> Sides a -> Bool
$c/= :: forall a. Eq a => Sides a -> Sides a -> Bool
/= :: Sides a -> Sides a -> Bool
Eq,(forall x. Sides a -> Rep (Sides a) x)
-> (forall x. Rep (Sides a) x -> Sides a) -> Generic (Sides a)
forall x. Rep (Sides a) x -> Sides a
forall x. Sides a -> Rep (Sides a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Sides a) x -> Sides a
forall a x. Sides a -> Rep (Sides a) x
$cfrom :: forall a x. Sides a -> Rep (Sides a) x
from :: forall x. Sides a -> Rep (Sides a) x
$cto :: forall a x. Rep (Sides a) x -> Sides a
to :: forall x. Rep (Sides a) x -> Sides a
Generic,Eq (Sides a)
Eq (Sides a) =>
(Sides a -> Sides a -> Ordering)
-> (Sides a -> Sides a -> Bool)
-> (Sides a -> Sides a -> Bool)
-> (Sides a -> Sides a -> Bool)
-> (Sides a -> Sides a -> Bool)
-> (Sides a -> Sides a -> Sides a)
-> (Sides a -> Sides a -> Sides a)
-> Ord (Sides a)
Sides a -> Sides a -> Bool
Sides a -> Sides a -> Ordering
Sides a -> Sides a -> Sides a
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 a. Ord a => Eq (Sides a)
forall a. Ord a => Sides a -> Sides a -> Bool
forall a. Ord a => Sides a -> Sides a -> Ordering
forall a. Ord a => Sides a -> Sides a -> Sides a
$ccompare :: forall a. Ord a => Sides a -> Sides a -> Ordering
compare :: Sides a -> Sides a -> Ordering
$c< :: forall a. Ord a => Sides a -> Sides a -> Bool
< :: Sides a -> Sides a -> Bool
$c<= :: forall a. Ord a => Sides a -> Sides a -> Bool
<= :: Sides a -> Sides a -> Bool
$c> :: forall a. Ord a => Sides a -> Sides a -> Bool
> :: Sides a -> Sides a -> Bool
$c>= :: forall a. Ord a => Sides a -> Sides a -> Bool
>= :: Sides a -> Sides a -> Bool
$cmax :: forall a. Ord a => Sides a -> Sides a -> Sides a
max :: Sides a -> Sides a -> Sides a
$cmin :: forall a. Ord a => Sides a -> Sides a -> Sides a
min :: Sides a -> Sides a -> Sides a
Ord,(forall m. Monoid m => Sides m -> m)
-> (forall m a. Monoid m => (a -> m) -> Sides a -> m)
-> (forall m a. Monoid m => (a -> m) -> Sides a -> m)
-> (forall a b. (a -> b -> b) -> b -> Sides a -> b)
-> (forall a b. (a -> b -> b) -> b -> Sides a -> b)
-> (forall b a. (b -> a -> b) -> b -> Sides a -> b)
-> (forall b a. (b -> a -> b) -> b -> Sides a -> b)
-> (forall a. (a -> a -> a) -> Sides a -> a)
-> (forall a. (a -> a -> a) -> Sides a -> a)
-> (forall a. Sides a -> [a])
-> (forall a. Sides a -> Bool)
-> (forall a. Sides a -> Int)
-> (forall a. Eq a => a -> Sides a -> Bool)
-> (forall a. Ord a => Sides a -> a)
-> (forall a. Ord a => Sides a -> a)
-> (forall a. Num a => Sides a -> a)
-> (forall a. Num a => Sides a -> a)
-> Foldable Sides
forall a. Eq a => a -> Sides a -> Bool
forall a. Num a => Sides a -> a
forall a. Ord a => Sides a -> a
forall m. Monoid m => Sides m -> m
forall a. Sides a -> Bool
forall a. Sides a -> Int
forall a. Sides a -> [a]
forall a. (a -> a -> a) -> Sides a -> a
forall m a. Monoid m => (a -> m) -> Sides a -> m
forall b a. (b -> a -> b) -> b -> Sides a -> b
forall a b. (a -> b -> b) -> b -> Sides 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
$cfold :: forall m. Monoid m => Sides m -> m
fold :: forall m. Monoid m => Sides m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Sides a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Sides a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Sides a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Sides a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Sides a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Sides a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Sides a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Sides a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Sides a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Sides a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Sides a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Sides a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Sides a -> a
foldr1 :: forall a. (a -> a -> a) -> Sides a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Sides a -> a
foldl1 :: forall a. (a -> a -> a) -> Sides a -> a
$ctoList :: forall a. Sides a -> [a]
toList :: forall a. Sides a -> [a]
$cnull :: forall a. Sides a -> Bool
null :: forall a. Sides a -> Bool
$clength :: forall a. Sides a -> Int
length :: forall a. Sides a -> Int
$celem :: forall a. Eq a => a -> Sides a -> Bool
elem :: forall a. Eq a => a -> Sides a -> Bool
$cmaximum :: forall a. Ord a => Sides a -> a
maximum :: forall a. Ord a => Sides a -> a
$cminimum :: forall a. Ord a => Sides a -> a
minimum :: forall a. Ord a => Sides a -> a
$csum :: forall a. Num a => Sides a -> a
sum :: forall a. Num a => Sides a -> a
$cproduct :: forall a. Num a => Sides a -> a
product :: forall a. Num a => Sides a -> a
Foldable,(forall a b. (a -> b) -> Sides a -> Sides b)
-> (forall a b. a -> Sides b -> Sides a) -> Functor Sides
forall a b. a -> Sides b -> Sides a
forall a b. (a -> b) -> Sides a -> Sides b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Sides a -> Sides b
fmap :: forall a b. (a -> b) -> Sides a -> Sides b
$c<$ :: forall a b. a -> Sides b -> Sides a
<$ :: forall a b. a -> Sides b -> Sides a
Functor,Functor Sides
Foldable Sides
(Functor Sides, Foldable Sides) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Sides a -> f (Sides b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Sides (f a) -> f (Sides a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Sides a -> m (Sides b))
-> (forall (m :: * -> *) a. Monad m => Sides (m a) -> m (Sides a))
-> Traversable Sides
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 => Sides (m a) -> m (Sides a)
forall (f :: * -> *) a. Applicative f => Sides (f a) -> f (Sides a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Sides a -> m (Sides b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Sides a -> f (Sides b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Sides a -> f (Sides b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Sides a -> f (Sides b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Sides (f a) -> f (Sides a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Sides (f a) -> f (Sides a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Sides a -> m (Sides b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Sides a -> m (Sides b)
$csequence :: forall (m :: * -> *) a. Monad m => Sides (m a) -> m (Sides a)
sequence :: forall (m :: * -> *) a. Monad m => Sides (m a) -> m (Sides a)
Traversable)

-- | Access the north side
north :: Lens' (Sides a) a
north :: forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
north = (Sides a -> a)
-> (Sides a -> a -> Sides a) -> Lens (Sides a) (Sides a) a a
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Sides a -> a
forall a. Sides a -> a
_north (\Sides a
s a
x -> Sides a
s { _north = x })

-- | Access the east side
east :: Lens' (Sides a) a
east :: forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
east = (Sides a -> a)
-> (Sides a -> a -> Sides a) -> Lens (Sides a) (Sides a) a a
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Sides a -> a
forall a. Sides a -> a
_east  (\Sides a
s a
x -> Sides a
s { _east  = x })

-- | Access the south side
south :: Lens' (Sides a) a
south :: forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
south = (Sides a -> a)
-> (Sides a -> a -> Sides a) -> Lens (Sides a) (Sides a) a a
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Sides a -> a
forall a. Sides a -> a
_south (\Sides a
s a
x -> Sides a
s { _south = x })

-- | Access the west side
west :: Lens' (Sides a) a
west :: forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
west  = (Sides a -> a)
-> (Sides a -> a -> Sides a) -> Lens (Sides a) (Sides a) a a
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Sides a -> a
forall a. Sides a -> a
_west  (\Sides a
s a
x -> Sides a
s { _west  = x })

instance Applicative Sides where
  pure :: forall a. a -> Sides a
pure a
x = a -> a -> a -> a -> Sides a
forall a. a -> a -> a -> a -> Sides a
Sides a
x a
x a
x a
x
  (Sides a -> b
f a -> b
g a -> b
h a -> b
i) <*> :: forall a b. Sides (a -> b) -> Sides a -> Sides b
<*> (Sides a
a a
b a
c a
d) = b -> b -> b -> b -> Sides b
forall a. a -> a -> a -> a -> Sides a
Sides (a -> b
f a
a) (a -> b
g a
b) (a -> b
h a
c) (a -> b
i a
d)

instance Foldable1 Sides where
  foldMap1 :: forall m a. Semigroup m => (a -> m) -> Sides a -> m
foldMap1 a -> m
f (Sides a
a a
b a
c a
d) = a -> m
f a
a m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f a
b m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f a
c m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f a
d
instance Traversable1 Sides where
  traverse1 :: forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> Sides a -> f (Sides b)
traverse1 a -> f b
f (Sides a
a a
b a
c a
d) = b -> b -> b -> b -> Sides b
forall a. a -> a -> a -> a -> Sides a
Sides (b -> b -> b -> b -> Sides b) -> f b -> f (b -> b -> b -> Sides b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a f (b -> b -> b -> Sides b) -> f b -> f (b -> b -> Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> a -> f b
f a
b f (b -> b -> Sides b) -> f b -> f (b -> Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> a -> f b
f a
c f (b -> Sides b) -> f b -> f (Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
<.> a -> f b
f a
d

instance Semigroup a => Semigroup (Sides a) where
  Sides a
s <> :: Sides a -> Sides a -> Sides a
<> Sides a
s' = a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>) (a -> a -> a) -> Sides a -> Sides (a -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Sides a
s Sides (a -> a) -> Sides a -> Sides a
forall a b. Sides (a -> b) -> Sides a -> Sides b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Sides a
s'
instance Monoid a => Monoid (Sides a) where
  mempty :: Sides a
mempty = a -> Sides a
forall a. a -> Sides a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Monoid a => a
mempty


type instance Index   (Sides a) = CardinalDirection
type instance IxValue (Sides a) = a

instance Ixed (Sides a) where
  ix :: Index (Sides a) -> Traversal' (Sides a) (IxValue (Sides a))
ix = \case
    Index (Sides a)
CardinalDirection
North -> (a -> f a) -> Sides a -> f (Sides a)
(IxValue (Sides a) -> f (IxValue (Sides a)))
-> Sides a -> f (Sides a)
forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
north
    Index (Sides a)
CardinalDirection
East  -> (a -> f a) -> Sides a -> f (Sides a)
(IxValue (Sides a) -> f (IxValue (Sides a)))
-> Sides a -> f (Sides a)
forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
east
    Index (Sides a)
CardinalDirection
South -> (a -> f a) -> Sides a -> f (Sides a)
(IxValue (Sides a) -> f (IxValue (Sides a)))
-> Sides a -> f (Sides a)
forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
south
    Index (Sides a)
CardinalDirection
West  -> (a -> f a) -> Sides a -> f (Sides a)
(IxValue (Sides a) -> f (IxValue (Sides a)))
-> Sides a -> f (Sides a)
forall a (f :: * -> *).
Functor f =>
(a -> f a) -> Sides a -> f (Sides a)
west

instance FunctorWithIndex CardinalDirection Sides where
  imap :: forall a b. (CardinalDirection -> a -> b) -> Sides a -> Sides b
imap CardinalDirection -> a -> b
f (Sides a
n a
e a
s a
w) = b -> b -> b -> b -> Sides b
forall a. a -> a -> a -> a -> Sides a
Sides (CardinalDirection -> a -> b
f CardinalDirection
North a
n) (CardinalDirection -> a -> b
f CardinalDirection
East a
e) (CardinalDirection -> a -> b
f CardinalDirection
South a
s) (CardinalDirection -> a -> b
f CardinalDirection
West a
w)

instance FoldableWithIndex CardinalDirection Sides where
  ifoldMap :: forall m a.
Monoid m =>
(CardinalDirection -> a -> m) -> Sides a -> m
ifoldMap CardinalDirection -> a -> m
f (Sides a
n a
e a
s a
w) = CardinalDirection -> a -> m
f CardinalDirection
North a
n m -> m -> m
forall a. Semigroup a => a -> a -> a
<> CardinalDirection -> a -> m
f CardinalDirection
East a
e m -> m -> m
forall a. Semigroup a => a -> a -> a
<> CardinalDirection -> a -> m
f CardinalDirection
South a
s m -> m -> m
forall a. Semigroup a => a -> a -> a
<> CardinalDirection -> a -> m
f CardinalDirection
West a
w

instance TraversableWithIndex CardinalDirection Sides where
  itraverse :: forall (f :: * -> *) a b.
Applicative f =>
(CardinalDirection -> a -> f b) -> Sides a -> f (Sides b)
itraverse CardinalDirection -> a -> f b
f (Sides a
n a
e a
s a
w) = b -> b -> b -> b -> Sides b
forall a. a -> a -> a -> a -> Sides a
Sides (b -> b -> b -> b -> Sides b) -> f b -> f (b -> b -> b -> Sides b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CardinalDirection -> a -> f b
f CardinalDirection
North a
n f (b -> b -> b -> Sides b) -> f b -> f (b -> b -> Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CardinalDirection -> a -> f b
f CardinalDirection
East a
e f (b -> b -> Sides b) -> f b -> f (b -> Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CardinalDirection -> a -> f b
f CardinalDirection
South a
s f (b -> Sides b) -> f b -> f (Sides b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> CardinalDirection -> a -> f b
f CardinalDirection
West a
w


-- | Constructs a Sides value that indicates the appropriate
-- direction.
sideDirections :: Sides CardinalDirection
sideDirections :: Sides CardinalDirection
sideDirections = CardinalDirection
-> CardinalDirection
-> CardinalDirection
-> CardinalDirection
-> Sides CardinalDirection
forall a. a -> a -> a -> a -> Sides a
Sides CardinalDirection
North CardinalDirection
East CardinalDirection
South CardinalDirection
West

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

-- | The top side of the box, from left to right.
topSide :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
        => rectangle  -> ClosedLineSegment point
topSide :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
topSide = (\(Corners point
l point
r point
_ point
_) -> point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
l point
r) (Corners point -> ClosedLineSegment point)
-> (rectangle -> Corners point)
-> rectangle
-> ClosedLineSegment point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rectangle -> Corners point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Corners point
corners

-- | Oriented from *left to right*
bottomSide :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
           => rectangle  -> ClosedLineSegment point
bottomSide :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
bottomSide = (\(Corners point
_ point
_ point
r point
l) -> point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
l point
r) (Corners point -> ClosedLineSegment point)
-> (rectangle -> Corners point)
-> rectangle
-> ClosedLineSegment point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rectangle -> Corners point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Corners point
corners

-- | Left side of the box, from bottom to top
leftSide  :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
          => rectangle -> ClosedLineSegment point
leftSide :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
leftSide = (\(Corners point
t point
_ point
_ point
b) -> point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
b point
t) (Corners point -> ClosedLineSegment point)
-> (rectangle -> Corners point)
-> rectangle
-> ClosedLineSegment point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rectangle -> Corners point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Corners point
corners

-- | The right side, oriented from *bottom* to top
rightSide :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
          => rectangle -> ClosedLineSegment point
rightSide :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
rightSide = (\(Corners point
_ point
t point
b point
_) -> point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
b point
t) (Corners point -> ClosedLineSegment point)
-> (rectangle -> Corners point)
-> rectangle
-> ClosedLineSegment point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rectangle -> Corners point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Corners point
corners


-- | The sides of the rectangle, in order (Top, Right, Bottom, Left). The sides
-- themselves are also oriented in clockwise order. If, you want them in the
-- same order as the functions `topSide`, `bottomSide`, `leftSide`, and
-- `rightSide`, use `sides'` instead.
sides   :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
        => rectangle -> Sides (ClosedLineSegment point)
sides :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Sides (ClosedLineSegment point)
sides rectangle
r = let Corners point
nw point
ne point
se point
sw = rectangle -> Corners point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Corners point
corners rectangle
r
          in ClosedLineSegment point
-> ClosedLineSegment point
-> ClosedLineSegment point
-> ClosedLineSegment point
-> Sides (ClosedLineSegment point)
forall a. a -> a -> a -> a -> Sides a
Sides (point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
nw point
ne) (point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
ne point
se)
                   (point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
se point
sw) (point -> point -> ClosedLineSegment point
forall point. point -> point -> ClosedLineSegment point
ClosedLineSegment point
sw point
nw)

-- | The sides of the rectangle. The order of the segments is (Top, Right,
-- Bottom, Left).  Note that the segments themselves, are oriented as described
-- by the functions topSide, bottomSide, leftSide, rightSide (basically: from
-- left to right, and from bottom to top). If you want the segments oriented
-- along the boundary of the rectangle, use the `sides` function instead.
sides'   :: (Num r, Rectangle_ rectangle point, Point_ point 2 r
           )
         => rectangle -> Sides (ClosedLineSegment point)
sides' :: forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Sides (ClosedLineSegment point)
sides' rectangle
r = ClosedLineSegment point
-> ClosedLineSegment point
-> ClosedLineSegment point
-> ClosedLineSegment point
-> Sides (ClosedLineSegment point)
forall a. a -> a -> a -> a -> Sides a
Sides (rectangle -> ClosedLineSegment point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
topSide rectangle
r) (rectangle -> ClosedLineSegment point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
rightSide rectangle
r) (rectangle -> ClosedLineSegment point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
bottomSide rectangle
r) (rectangle -> ClosedLineSegment point
forall r rectangle point.
(Num r, Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> ClosedLineSegment point
leftSide rectangle
r)


-- | The side values of the rectangle, i.e. the coordinates of the top, right, bottom, and
-- left sides.
sideValues      :: (Rectangle_ rectangle point, Point_ point 2 r
                   ) => rectangle -> Sides r
sideValues :: forall rectangle point r.
(Rectangle_ rectangle point, Point_ point 2 r) =>
rectangle -> Sides r
sideValues rectangle
rect = r -> r -> r -> r -> Sides r
forall a. a -> a -> a -> a -> Sides a
Sides (rectangle
rectrectangle -> Getting r rectangle r -> r
forall s a. s -> Getting a s a -> a
^.(point -> Const r point) -> rectangle -> Const r rectangle
forall box point. HasMaxPoint box point => Lens' box point
Lens' rectangle point
maxPoint((point -> Const r point) -> rectangle -> Const r rectangle)
-> ((r -> Const r r) -> point -> Const r point)
-> Getting r rectangle r
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> Const r r) -> point -> Const r point
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
yCoord) (rectangle
rectrectangle -> Getting r rectangle r -> r
forall s a. s -> Getting a s a -> a
^.(point -> Const r point) -> rectangle -> Const r rectangle
forall box point. HasMaxPoint box point => Lens' box point
Lens' rectangle point
maxPoint((point -> Const r point) -> rectangle -> Const r rectangle)
-> ((r -> Const r r) -> point -> Const r point)
-> Getting r rectangle r
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> Const r r) -> point -> Const r point
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord)
                        (rectangle
rectrectangle -> Getting r rectangle r -> r
forall s a. s -> Getting a s a -> a
^.(point -> Const r point) -> rectangle -> Const r rectangle
forall box point. HasMinPoint box point => Lens' box point
Lens' rectangle point
minPoint((point -> Const r point) -> rectangle -> Const r rectangle)
-> ((r -> Const r r) -> point -> Const r point)
-> Getting r rectangle r
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> Const r r) -> point -> Const r point
forall (d :: Nat) point r.
(2 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
yCoord) (rectangle
rectrectangle -> Getting r rectangle r -> r
forall s a. s -> Getting a s a -> a
^.(point -> Const r point) -> rectangle -> Const r rectangle
forall box point. HasMinPoint box point => Lens' box point
Lens' rectangle point
minPoint((point -> Const r point) -> rectangle -> Const r rectangle)
-> ((r -> Const r r) -> point -> Const r point)
-> Getting r rectangle r
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(r -> Const r r) -> point -> Const r point
forall (d :: Nat) point r.
(1 <= d, Point_ point d r) =>
IndexedLens' Int point r
IndexedLens' Int point r
xCoord)


-- | Gets the four halfplanes so that the box is the intersection of the halfplanes.
intersectingHalfPlanes      :: (Rectangle_ rectangle point, Point_ point 2 r, Num r)
                            => rectangle -> Sides (HalfSpaceF (LinePV 2 r))
intersectingHalfPlanes :: forall rectangle point r.
(Rectangle_ rectangle point, Point_ point 2 r, Num r) =>
rectangle -> Sides (HalfSpaceF (LinePV 2 r))
intersectingHalfPlanes rectangle
rect =
  HalfSpaceF (LinePV 2 r)
-> HalfSpaceF (LinePV 2 r)
-> HalfSpaceF (LinePV 2 r)
-> HalfSpaceF (LinePV 2 r)
-> Sides (HalfSpaceF (LinePV 2 r))
forall a. a -> a -> a -> a -> Sides a
Sides (Sign -> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall boundingHyperPlane.
Sign -> boundingHyperPlane -> HalfSpaceF boundingHyperPlane
HalfSpace Sign
Negative (LinePV 2 r -> HalfSpaceF (LinePV 2 r))
-> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall a b. (a -> b) -> a -> b
$ Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (rectangle
rectrectangle -> Getting (Point 2 r) rectangle (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.(point -> Const (Point 2 r) point)
-> rectangle -> Const (Point 2 r) rectangle
forall box point. HasMaxPoint box point => Lens' box point
Lens' rectangle point
maxPoint((point -> Const (Point 2 r) point)
 -> rectangle -> Const (Point 2 r) rectangle)
-> ((Point 2 r -> Const (Point 2 r) (Point 2 r))
    -> point -> Const (Point 2 r) point)
-> Getting (Point 2 r) rectangle (Point 2 r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point 2 r -> Const (Point 2 r) (Point 2 r))
-> point -> Const (Point 2 r) point
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point 2 r)
asPoint) (r -> r -> Vector 2 r
forall r. r -> r -> Vector 2 r
Vector2 r
1 r
0))
        (Sign -> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall boundingHyperPlane.
Sign -> boundingHyperPlane -> HalfSpaceF boundingHyperPlane
HalfSpace Sign
Negative (LinePV 2 r -> HalfSpaceF (LinePV 2 r))
-> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall a b. (a -> b) -> a -> b
$ Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (rectangle
rectrectangle -> Getting (Point 2 r) rectangle (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.(point -> Const (Point 2 r) point)
-> rectangle -> Const (Point 2 r) rectangle
forall box point. HasMaxPoint box point => Lens' box point
Lens' rectangle point
maxPoint((point -> Const (Point 2 r) point)
 -> rectangle -> Const (Point 2 r) rectangle)
-> ((Point 2 r -> Const (Point 2 r) (Point 2 r))
    -> point -> Const (Point 2 r) point)
-> Getting (Point 2 r) rectangle (Point 2 r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point 2 r -> Const (Point 2 r) (Point 2 r))
-> point -> Const (Point 2 r) point
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point 2 r)
asPoint) (r -> r -> Vector 2 r
forall r. r -> r -> Vector 2 r
Vector2 r
0 r
1))
        (Sign -> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall boundingHyperPlane.
Sign -> boundingHyperPlane -> HalfSpaceF boundingHyperPlane
HalfSpace Sign
Positive (LinePV 2 r -> HalfSpaceF (LinePV 2 r))
-> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall a b. (a -> b) -> a -> b
$ Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (rectangle
rectrectangle -> Getting (Point 2 r) rectangle (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.(point -> Const (Point 2 r) point)
-> rectangle -> Const (Point 2 r) rectangle
forall box point. HasMinPoint box point => Lens' box point
Lens' rectangle point
minPoint((point -> Const (Point 2 r) point)
 -> rectangle -> Const (Point 2 r) rectangle)
-> ((Point 2 r -> Const (Point 2 r) (Point 2 r))
    -> point -> Const (Point 2 r) point)
-> Getting (Point 2 r) rectangle (Point 2 r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point 2 r -> Const (Point 2 r) (Point 2 r))
-> point -> Const (Point 2 r) point
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point 2 r)
asPoint) (r -> r -> Vector 2 r
forall r. r -> r -> Vector 2 r
Vector2 r
1 r
0))
        (Sign -> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall boundingHyperPlane.
Sign -> boundingHyperPlane -> HalfSpaceF boundingHyperPlane
HalfSpace Sign
Positive (LinePV 2 r -> HalfSpaceF (LinePV 2 r))
-> LinePV 2 r -> HalfSpaceF (LinePV 2 r)
forall a b. (a -> b) -> a -> b
$ Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (rectangle
rectrectangle -> Getting (Point 2 r) rectangle (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.(point -> Const (Point 2 r) point)
-> rectangle -> Const (Point 2 r) rectangle
forall box point. HasMinPoint box point => Lens' box point
Lens' rectangle point
minPoint((point -> Const (Point 2 r) point)
 -> rectangle -> Const (Point 2 r) rectangle)
-> ((Point 2 r -> Const (Point 2 r) (Point 2 r))
    -> point -> Const (Point 2 r) point)
-> Getting (Point 2 r) rectangle (Point 2 r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point 2 r -> Const (Point 2 r) (Point 2 r))
-> point -> Const (Point 2 r) point
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point 2 r)
asPoint) (r -> r -> Vector 2 r
forall r. r -> r -> Vector 2 r
Vector2 r
0 r
1))