{-# LANGUAGE UndecidableInstances #-}
--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.LineSegment.Internal
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- Line segment data type and some basic functions on line segments
--
--------------------------------------------------------------------------------
module HGeometry.LineSegment.Internal
  ( LineSegment(LineSegment, ClosedLineSegment, OpenLineSegment)
  , ClosedLineSegment
  , OpenLineSegment
  , EndPoint(EndPoint,OpenE,ClosedE)
  , AnEndPoint(AnEndPoint,AnOpenE,AnClosedE)
  , module HGeometry.LineSegment.Class
  , spanIn
  , EndPoint_(..)
  , asALineSegment

  , StartEnd(..)

  , inPerpendicularSlab
  ) where


import Control.Lens
import Data.Functor.Apply qualified as Apply
import Data.Kind (Type)
import HGeometry.Box.Boxable
import HGeometry.Intersection
import HGeometry.Interval
import HGeometry.Line.Class
import HGeometry.Line.PointAndVector
import HGeometry.LineSegment.Class
import HGeometry.Point
import HGeometry.Properties (NumType, Dimension)
import HGeometry.Transformation
import HGeometry.Vector
import Text.Read
import Data.Foldable1
import GHC.Generics (Generic)
import Control.DeepSeq
import Hiraffe.Graph.Class(HasVertices'(..), HasVertices(..))

-- import HGeometry.Number.Real.Rational
-- import Debug.Trace

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

-- >>> :{
-- testseg :: ClosedLineSegment (Point 2 Double)
-- testseg = ClosedLineSegment (Point2 5.0 6.0) (Point2 10.0 10.0)
--
-- myPoint :: Point 2 Double
-- myPoint = interpolate 0.5 testseg
-- :}



-- testI :: ClosedInterval (Point 2 Double)
-- testI = ClosedInterval (Point2 5.0 6.0) (Point2 10.0 10.0)






-- | Data type representing intervals
type LineSegment :: (Type -> Type) -> Type -> Type
newtype LineSegment endPoint point = MkLineSegment (Interval endPoint point)
              deriving ((forall x.
 LineSegment endPoint point -> Rep (LineSegment endPoint point) x)
-> (forall x.
    Rep (LineSegment endPoint point) x -> LineSegment endPoint point)
-> Generic (LineSegment endPoint point)
forall x.
Rep (LineSegment endPoint point) x -> LineSegment endPoint point
forall x.
LineSegment endPoint point -> Rep (LineSegment endPoint point) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (endPoint :: * -> *) point x.
Rep (LineSegment endPoint point) x -> LineSegment endPoint point
forall (endPoint :: * -> *) point x.
LineSegment endPoint point -> Rep (LineSegment endPoint point) x
$cfrom :: forall (endPoint :: * -> *) point x.
LineSegment endPoint point -> Rep (LineSegment endPoint point) x
from :: forall x.
LineSegment endPoint point -> Rep (LineSegment endPoint point) x
$cto :: forall (endPoint :: * -> *) point x.
Rep (LineSegment endPoint point) x -> LineSegment endPoint point
to :: forall x.
Rep (LineSegment endPoint point) x -> LineSegment endPoint point
Generic)
              deriving newtype (LineSegment endPoint point -> ()
(LineSegment endPoint point -> ())
-> NFData (LineSegment endPoint point)
forall a. (a -> ()) -> NFData a
forall (endPoint :: * -> *) point.
NFData (endPoint point) =>
LineSegment endPoint point -> ()
$crnf :: forall (endPoint :: * -> *) point.
NFData (endPoint point) =>
LineSegment endPoint point -> ()
rnf :: LineSegment endPoint point -> ()
NFData)

-- | A type representing Closed LineSegments
type ClosedLineSegment point = LineSegment (EndPoint Closed) point

-- | A type representing Open LineSegments
type OpenLineSegment point   = LineSegment (EndPoint Open) point

-- | Construct a line Segment
pattern LineSegment     :: endPoint point -> endPoint point -> LineSegment endPoint point
pattern $bLineSegment :: forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
$mLineSegment :: forall {r} {endPoint :: * -> *} {point}.
LineSegment endPoint point
-> (endPoint point -> endPoint point -> r) -> ((# #) -> r) -> r
LineSegment p q = MkLineSegment (Interval p q)
{-# COMPLETE LineSegment #-}

-- | Construct a closed interval
pattern ClosedLineSegment     :: point -> point -> ClosedLineSegment point
pattern $bClosedLineSegment :: forall point. point -> point -> ClosedLineSegment point
$mClosedLineSegment :: forall {r} {point}.
ClosedLineSegment point
-> (point -> point -> r) -> ((# #) -> r) -> r
ClosedLineSegment s t = LineSegment (ClosedE s) (ClosedE t)
{-# COMPLETE ClosedLineSegment #-}

-- | Construct an open ended interval
pattern OpenLineSegment     :: point -> point -> OpenLineSegment point
pattern $bOpenLineSegment :: forall point. point -> point -> OpenLineSegment point
$mOpenLineSegment :: forall {r} {point}.
OpenLineSegment point -> (point -> point -> r) -> ((# #) -> r) -> r
OpenLineSegment s t = LineSegment (OpenE s) (OpenE t)
{-# COMPLETE OpenLineSegment #-}

type instance NumType   (LineSegment endPoint point) = NumType point
type instance Dimension (LineSegment endPoint point) = Dimension point

deriving instance (Eq (endPoint point)
                  ) => Eq (LineSegment endPoint point)
deriving instance (Ord (endPoint point)
                  ) => Ord (LineSegment endPoint point)


instance Foldable endPoint => Foldable (LineSegment endPoint) where
  foldMap :: forall m a. Monoid m => (a -> m) -> LineSegment endPoint a -> m
foldMap a -> m
f (LineSegment endPoint a
s endPoint a
t) = (a -> m) -> endPoint a -> m
forall m a. Monoid m => (a -> m) -> endPoint a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f endPoint a
s m -> m -> m
forall a. Semigroup a => a -> a -> a
<> (a -> m) -> endPoint a -> m
forall m a. Monoid m => (a -> m) -> endPoint a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f endPoint a
t

instance Functor endPoint => Functor (LineSegment endPoint) where
  fmap :: forall a b.
(a -> b) -> LineSegment endPoint a -> LineSegment endPoint b
fmap a -> b
f (LineSegment endPoint a
s endPoint a
t) = endPoint b -> endPoint b -> LineSegment endPoint b
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment ((a -> b) -> endPoint a -> endPoint b
forall a b. (a -> b) -> endPoint a -> endPoint b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f endPoint a
s) ((a -> b) -> endPoint a -> endPoint b
forall a b. (a -> b) -> endPoint a -> endPoint b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f endPoint a
t)

instance Traversable endPoint => Traversable (LineSegment endPoint) where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> LineSegment endPoint a -> f (LineSegment endPoint b)
traverse a -> f b
f (LineSegment endPoint a
s endPoint a
t) = endPoint b -> endPoint b -> LineSegment endPoint b
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment (endPoint b -> endPoint b -> LineSegment endPoint b)
-> f (endPoint b) -> f (endPoint b -> LineSegment endPoint b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> endPoint a -> f (endPoint b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse a -> f b
f endPoint a
s f (endPoint b -> LineSegment endPoint b)
-> f (endPoint b) -> f (LineSegment endPoint b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> f b) -> endPoint a -> f (endPoint b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse a -> f b
f endPoint a
t

instance Foldable1 endPoint => Foldable1 (LineSegment endPoint) where
  foldMap1 :: forall m a. Semigroup m => (a -> m) -> LineSegment endPoint a -> m
foldMap1 a -> m
f (LineSegment endPoint a
s endPoint a
t) = (a -> m) -> endPoint a -> m
forall m a. Semigroup m => (a -> m) -> endPoint a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1 a -> m
f endPoint a
s m -> m -> m
forall a. Semigroup a => a -> a -> a
<> (a -> m) -> endPoint a -> m
forall m a. Semigroup m => (a -> m) -> endPoint a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1 a -> m
f endPoint a
t

instance Traversable1 endPoint => Traversable1 (LineSegment endPoint) where
  traverse1 :: forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> LineSegment endPoint a -> f (LineSegment endPoint b)
traverse1 a -> f b
f (LineSegment endPoint a
s endPoint a
t) = endPoint b -> endPoint b -> LineSegment endPoint b
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment (endPoint b -> endPoint b -> LineSegment endPoint b)
-> f (endPoint b) -> f (endPoint b -> LineSegment endPoint b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> endPoint a -> f (endPoint b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 a -> f b
f endPoint a
s f (endPoint b -> LineSegment endPoint b)
-> f (endPoint b) -> f (LineSegment endPoint b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
Apply.<.> (a -> f b) -> endPoint a -> f (endPoint b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 a -> f b
f endPoint a
t



-- | Lens to get the underlying interval
_LineSegmentInterval :: Iso (LineSegment endPoint point) (LineSegment endPoint' point')
                            (Interval endPoint point)    (Interval    endPoint' point')
_LineSegmentInterval :: forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval = (LineSegment endPoint point -> Interval endPoint point)
-> (Interval endPoint' point' -> LineSegment endPoint' point')
-> Iso
     (LineSegment endPoint point)
     (LineSegment endPoint' point')
     (Interval endPoint point)
     (Interval endPoint' point')
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(MkLineSegment Interval endPoint point
i) -> Interval endPoint point
i) Interval endPoint' point' -> LineSegment endPoint' point'
forall (endPoint :: * -> *) point.
Interval endPoint point -> LineSegment endPoint point
MkLineSegment

instance ( IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         ) => HasStart (LineSegment endPoint point) point where
  start :: Lens' (LineSegment endPoint point) point
start = (Interval endPoint point -> f (Interval endPoint point))
-> LineSegment endPoint point -> f (LineSegment endPoint point)
forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval((Interval endPoint point -> f (Interval endPoint point))
 -> LineSegment endPoint point -> f (LineSegment endPoint point))
-> ((point -> f point)
    -> Interval endPoint point -> f (Interval endPoint point))
-> (point -> f point)
-> LineSegment endPoint point
-> f (LineSegment endPoint point)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(point -> f point)
-> Interval endPoint point -> f (Interval endPoint point)
forall seg p. HasStart seg p => Lens' seg p
Lens' (Interval endPoint point) point
start

instance ( IxValue (endPoint point) ~ point
         ) => HasStartPoint (LineSegment endPoint point) (endPoint point) where
  startPoint :: Lens' (LineSegment endPoint point) (endPoint point)
startPoint = (Interval endPoint point -> f (Interval endPoint point))
-> LineSegment endPoint point -> f (LineSegment endPoint point)
forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval((Interval endPoint point -> f (Interval endPoint point))
 -> LineSegment endPoint point -> f (LineSegment endPoint point))
-> ((endPoint point -> f (endPoint point))
    -> Interval endPoint point -> f (Interval endPoint point))
-> (endPoint point -> f (endPoint point))
-> LineSegment endPoint point
-> f (LineSegment endPoint point)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(endPoint point -> f (endPoint point))
-> Interval endPoint point -> f (Interval endPoint point)
forall seg p. HasStartPoint seg p => Lens' seg p
Lens' (Interval endPoint point) (endPoint point)
startPoint


instance ( IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         ) => HasEnd (LineSegment endPoint point) point where
  end :: Lens' (LineSegment endPoint point) point
end = (Interval endPoint point -> f (Interval endPoint point))
-> LineSegment endPoint point -> f (LineSegment endPoint point)
forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval((Interval endPoint point -> f (Interval endPoint point))
 -> LineSegment endPoint point -> f (LineSegment endPoint point))
-> ((point -> f point)
    -> Interval endPoint point -> f (Interval endPoint point))
-> (point -> f point)
-> LineSegment endPoint point
-> f (LineSegment endPoint point)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(point -> f point)
-> Interval endPoint point -> f (Interval endPoint point)
forall seg p. HasEnd seg p => Lens' seg p
Lens' (Interval endPoint point) point
end

instance ( IxValue (endPoint point) ~ point
         ) => HasEndPoint (LineSegment endPoint point) (endPoint point) where
  endPoint :: Lens' (LineSegment endPoint point) (endPoint point)
endPoint = (Interval endPoint point -> f (Interval endPoint point))
-> LineSegment endPoint point -> f (LineSegment endPoint point)
forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval((Interval endPoint point -> f (Interval endPoint point))
 -> LineSegment endPoint point -> f (LineSegment endPoint point))
-> ((endPoint point -> f (endPoint point))
    -> Interval endPoint point -> f (Interval endPoint point))
-> (endPoint point -> f (endPoint point))
-> LineSegment endPoint point
-> f (LineSegment endPoint point)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(endPoint point -> f (endPoint point))
-> Interval endPoint point -> f (Interval endPoint point)
forall seg p. HasEndPoint seg p => Lens' seg p
Lens' (Interval endPoint point) (endPoint point)
endPoint

type instance StartPointOf (LineSegment endPoint point) = endPoint point
type instance EndPointOf   (LineSegment endPoint point) = endPoint point

instance ( IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         ) => IntervalLike_ (LineSegment endPoint point) point where

instance ( IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         , Point_ point (Dimension point) (NumType point)
         ) => LineSegment_ (LineSegment endPoint point) point where

instance ( IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         , Point_ point (Dimension point) (NumType point)
         ) => ConstructableLineSegment_ (LineSegment endPoint point) point where
  uncheckedLineSegment :: point -> point -> LineSegment endPoint point
uncheckedLineSegment point
s point
t = endPoint point -> endPoint point -> LineSegment endPoint point
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment (IxValue (endPoint point) -> endPoint point
forall endPoint. EndPoint_ endPoint => IxValue endPoint -> endPoint
mkEndPoint point
IxValue (endPoint point)
s) (IxValue (endPoint point) -> endPoint point
forall endPoint. EndPoint_ endPoint => IxValue endPoint -> endPoint
mkEndPoint point
IxValue (endPoint point)
t)

instance ( Point_ point (Dimension point) (NumType point)
         ) => ClosedLineSegment_ (ClosedLineSegment point) point where

instance ( Point_ point (Dimension point) (NumType point)
         ) => OpenLineSegment_ (OpenLineSegment point) point where

instance ( Traversable1 endPoint
         , Dimension point ~ Dimension point'
         , Point_ point  (Dimension point) (NumType point)
         , Point_ point' (Dimension point) (NumType point')
         ) => HasPoints (LineSegment endPoint point) (LineSegment endPoint point')
                        point                        point' where
  allPoints :: forall (d :: Nat) r r'.
(Point_ point d r, Point_ point' d r',
 NumType (LineSegment endPoint point) ~ r,
 NumType (LineSegment endPoint point') ~ r',
 Dimension (LineSegment endPoint point) ~ d,
 Dimension (LineSegment endPoint point') ~ d) =>
Traversal1
  (LineSegment endPoint point)
  (LineSegment endPoint point')
  point
  point'
allPoints point -> f point'
f (LineSegment endPoint point
s endPoint point
t) = (endPoint point' -> endPoint point' -> LineSegment endPoint point')
-> f (endPoint point')
-> f (endPoint point')
-> f (LineSegment endPoint point')
forall a b c. (a -> b -> c) -> f a -> f b -> f c
forall (f :: * -> *) a b c.
Apply f =>
(a -> b -> c) -> f a -> f b -> f c
Apply.liftF2 endPoint point' -> endPoint point' -> LineSegment endPoint point'
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment ((point -> f point') -> endPoint point -> f (endPoint point')
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 point -> f point'
f endPoint point
s) ((point -> f point') -> endPoint point -> f (endPoint point')
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 point -> f point'
f endPoint point
t)


-- foo     :: ( Eq r
--          , Additive_ (VectorFamily' d r)
--          , IxValue (VectorFamily' d r) ~ r
--          , HasComponents (VectorFamily' d Bool) Bool
--          ) => Vector d r -> Vector d r -> Bool




instance ( Traversable1 endPoint
         , Point_ point d r
         , d ~ Dimension point, r ~  NumType point
         , Ord r
         , Ord (Vector d r)
         ) => IsBoxable (LineSegment endPoint point)


-- deriving instance (Show (Interval endPoint point)) => Show (LineSegment endPoint point)

instance {-# OVERLAPPABLE #-}
         ( Show (endPoint point)
         -- , OptCVector_ 2 (endPoint point)
         ) => Show (LineSegment endPoint point) where
  showsPrec :: Int -> LineSegment endPoint point -> ShowS
showsPrec Int
k (LineSegment endPoint point
s endPoint point
t) = Bool -> ShowS -> ShowS
showParen (Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
                                    String -> ShowS
showString String
"LineSegment "
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> endPoint point -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) endPoint point
s
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> endPoint point -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) endPoint point
t

instance {-# OVERLAPPING #-}
         ( Show point
         -- , OptCVector_ 2 point
         ) => Show (ClosedLineSegment point) where
  showsPrec :: Int -> ClosedLineSegment point -> ShowS
showsPrec Int
k (ClosedLineSegment point
s point
t) = Bool -> ShowS -> ShowS
showParen (Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
                                    String -> ShowS
showString String
"ClosedLineSegment "
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> point -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) point
s
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' '
                                    ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> point -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) point
t

appPrec :: Int
appPrec :: Int
appPrec = Int
10

instance ( Read (endPoint point) --, OptCVector_ 2 (endPoint point))
         ) => Read (LineSegment endPoint point) where
  readPrec :: ReadPrec (LineSegment endPoint point)
readPrec = ReadPrec (LineSegment endPoint point)
-> ReadPrec (LineSegment endPoint point)
forall a. ReadPrec a -> ReadPrec a
parens (Int
-> ReadPrec (LineSegment endPoint point)
-> ReadPrec (LineSegment endPoint point)
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
appPrec (ReadPrec (LineSegment endPoint point)
 -> ReadPrec (LineSegment endPoint point))
-> ReadPrec (LineSegment endPoint point)
-> ReadPrec (LineSegment endPoint point)
forall a b. (a -> b) -> a -> b
$ do
                          Ident "LineSegment" <- ReadPrec Lexeme
lexP
                          p <- step readPrec
                          q <- step readPrec
                          return (LineSegment p q))

instance {-# OVERLAPPING #-}
         (Read point -- , OptCVector_ 2 point)
         ) => Read (ClosedLineSegment point) where
  readPrec :: ReadPrec (ClosedLineSegment point)
readPrec = ReadPrec (ClosedLineSegment point)
-> ReadPrec (ClosedLineSegment point)
forall a. ReadPrec a -> ReadPrec a
parens (Int
-> ReadPrec (ClosedLineSegment point)
-> ReadPrec (ClosedLineSegment point)
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
appPrec (ReadPrec (ClosedLineSegment point)
 -> ReadPrec (ClosedLineSegment point))
-> ReadPrec (ClosedLineSegment point)
-> ReadPrec (ClosedLineSegment point)
forall a b. (a -> b) -> a -> b
$ do
                          Ident "ClosedLineSegment" <- ReadPrec Lexeme
lexP
                          p <- step readPrec
                          q <- step readPrec
                          return (ClosedLineSegment p q))


-- type instance VectorFamily d (LineSegment endPoint point) =
--   WrapVector d (Interval endPoint point) (LineSegment endPoint point)



instance ( Point_ point d r
         , Has_ Metric_ d r
         , EndPoint_ (endPoint point)
         , IxValue (endPoint point) ~ point
         , Num r
         ) => HasSupportingLine (LineSegment endPoint point) where
  supportingLine :: LineSegment endPoint point
-> LinePV
     (Dimension (LineSegment endPoint point))
     (NumType (LineSegment endPoint point))
supportingLine LineSegment endPoint point
seg = forall line point (d :: Nat) r.
(Line_ line d r, Point_ point d r, Num r) =>
point -> point -> line
lineThrough @(LinePV d r) @point
                                   (LineSegment endPoint point
segLineSegment endPoint point
-> Getting point (LineSegment endPoint point) point -> point
forall s a. s -> Getting a s a -> a
^.Getting point (LineSegment endPoint point) point
forall seg p. HasStart seg p => Lens' seg p
Lens' (LineSegment endPoint point) point
start) (LineSegment endPoint point
segLineSegment endPoint point
-> Getting point (LineSegment endPoint point) point -> point
forall s a. s -> Getting a s a -> a
^.Getting point (LineSegment endPoint point) point
forall seg p. HasEnd seg p => Lens' seg p
Lens' (LineSegment endPoint point) point
end)
  {-# INLINE supportingLine #-}

instance ( Fractional r, Ord r
         , HasSquaredEuclideanDistance point
         , Point_ point d r
         ) => HasSquaredEuclideanDistance (ClosedLineSegment point) where
  pointClosestToWithDistance :: forall r (d :: Nat) point.
(r ~ NumType (ClosedLineSegment point),
 d ~ Dimension (ClosedLineSegment point), Num r,
 Point_ point d r) =>
point -> ClosedLineSegment point -> (Point d r, r)
pointClosestToWithDistance point
q seg :: ClosedLineSegment point
seg@(ClosedLineSegment point
a point
b)
      | Point d r
m Point d r -> ClosedLineSegment point -> Bool
forall g h. HasIntersectionWith g h => g -> h -> Bool
`intersects` ClosedLineSegment point
seg = (Point d r, r)
(PointF (Vector d r), r)
z
      | Bool
otherwise          = ((PointF (Vector d r), r) -> r)
-> (PointF (Vector d r), r)
-> (PointF (Vector d r), r)
-> (PointF (Vector d r), r)
forall b a. Ord b => (a -> b) -> a -> a -> a
minOn (PointF (Vector d r), r) -> r
forall a b. (a, b) -> b
snd (point -> point -> (PointF (Vector d r), r)
forall g r (d :: Nat) point.
(HasSquaredEuclideanDistance g, r ~ NumType g, d ~ Dimension g,
 Num r, Point_ point d r) =>
point -> g -> (Point d r, r)
forall r (d :: Nat) point.
(r ~ NumType point, d ~ Dimension point, Num r,
 Point_ point d r) =>
point -> point -> (Point d r, r)
pointClosestToWithDistance point
q point
a)
                                       (point -> point -> (PointF (Vector d r), r)
forall g r (d :: Nat) point.
(HasSquaredEuclideanDistance g, r ~ NumType g, d ~ Dimension g,
 Num r, Point_ point d r) =>
point -> g -> (Point d r, r)
forall r (d :: Nat) point.
(r ~ NumType point, d ~ Dimension point, Num r,
 Point_ point d r) =>
point -> point -> (Point d r, r)
pointClosestToWithDistance point
q point
b)
    where
      z       :: (Point d r, r)
      z :: (Point d r, r)
z@(Point d r
m,r
_) = point -> LinePV d r -> (Point d r, r)
forall g r (d :: Nat) point.
(HasSquaredEuclideanDistance g, r ~ NumType g, d ~ Dimension g,
 Num r, Point_ point d r) =>
point -> g -> (Point d r, r)
forall r (d :: Nat) point.
(r ~ NumType (LinePV d r), d ~ Dimension (LinePV d r), Num r,
 Point_ point d r) =>
point -> LinePV d r -> (Point d r, r)
pointClosestToWithDistance point
q (ClosedLineSegment point
-> LinePV
     (Dimension (ClosedLineSegment point))
     (NumType (ClosedLineSegment point))
forall t.
HasSupportingLine t =>
t -> LinePV (Dimension t) (NumType t)
supportingLine ClosedLineSegment point
seg)

      minOn       :: Ord b => (a -> b) -> a -> a -> a
      minOn :: forall b a. Ord b => (a -> b) -> a -> a -> a
minOn a -> b
f a
x a
y = if a -> b
f a
x b -> b -> Bool
forall a. Ord a => a -> a -> Bool
<= a -> b
f a
y then a
x else a
y

-- type Intersection (Point d r) (ClosedLineSegment point)

instance ( HasOnSegment (LineSegment endPoint point) d
         , Point_ point d r
         , Fractional r, Ord r
         ) => Point d r `HasIntersectionWith` LineSegment endPoint point where
  -- >>> test `intersects` testseg
  -- True
  intersects :: Point d r -> LineSegment endPoint point -> Bool
intersects = Point d r -> LineSegment endPoint point -> Bool
forall lineSegment (d :: Nat) r point.
(HasOnSegment lineSegment d, Ord r, Point_ point d r,
 r ~ NumType lineSegment, d ~ Dimension lineSegment) =>
point -> lineSegment -> Bool
forall r point.
(Ord r, Point_ point d r, r ~ NumType (LineSegment endPoint point),
 d ~ Dimension (LineSegment endPoint point)) =>
point -> LineSegment endPoint point -> Bool
onSegment

instance {-# OVERLAPPING #-}
         ( HasOnSegment (LineSegment endPoint point) 2
         , Point_ point 2 r
         , Num r, Ord r
         , IxValue (endPoint point) ~ point, EndPoint_ (endPoint point)
         ) => Point 2 r `HasIntersectionWith` LineSegment endPoint point where
  -- >>> test `intersects` testseg
  -- True
  intersects :: Point 2 r -> LineSegment endPoint point -> Bool
intersects = Point 2 r -> LineSegment endPoint point -> Bool
forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onSegment2

-- | Implementation of OnSegment for 2 dimensional segments that only uses Ord and Num r
-- constraints.
--
onSegment2                          :: ( Point_ point 2 r, Point_ point' 2 r, Ord r, Num r
                                       , LineSegment_ lineSegment point')
                                    => point -> lineSegment -> Bool
onSegment2 :: forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onSegment2 point
q seg :: lineSegment
seg@(LineSegment_ point'
s point'
t) = point -> lineSegment -> Bool
forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
inPerpendicularSlab point
q lineSegment
seg Bool -> Bool -> Bool
&& point -> LinePV 2 r -> Bool
forall line (d :: Nat) point r.
(HasOnLine line d, Point_ point d r, Num r, Eq r, r ~ NumType line,
 d ~ Dimension line) =>
point -> line -> Bool
forall point r.
(Point_ point 2 r, Num r, Eq r, r ~ NumType (LinePV 2 r),
 2 ~ Dimension (LinePV 2 r)) =>
point -> LinePV 2 r -> Bool
onLine point
q LinePV 2 r
supLine
  where
    supLine :: LinePV 2 r
supLine = Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (point'
spoint' -> Getting (Point 2 r) point' (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.Getting (Point 2 r) point' (Point 2 r)
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point' (Point 2 r)
asPoint) (point'
t point' -> point' -> Vector 2 r
forall point (d :: Nat) r.
(Affine_ point d r, Num r) =>
point -> point -> Vector d r
.-. point'
s)
  -- note: we test whether we are in the slab first; since that involves less precision
  -- and thus tends to be faster (in case there is no intersection)

-- | Test if the given query point q lies in the slab perpendicular to
-- the given line segment
inPerpendicularSlab                          :: ( Point_ point 2 r, Point_ point' 2 r, Ord r, Num r
                                                , LineSegment_ lineSegment point'
                                                )
                                             => point -> lineSegment -> Bool
inPerpendicularSlab :: forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
inPerpendicularSlab point
q seg :: lineSegment
seg@(LineSegment_ point'
s point'
t) =
       EndPointType -> SideTest -> SideTest -> Bool
shouldBe (lineSegment
seglineSegment
-> Getting EndPointType lineSegment EndPointType -> EndPointType
forall s a. s -> Getting a s a -> a
^.(StartPointOf lineSegment
 -> Const EndPointType (StartPointOf lineSegment))
-> lineSegment -> Const EndPointType lineSegment
forall seg p. HasStartPoint seg p => Lens' seg p
Lens' lineSegment (StartPointOf lineSegment)
startPoint((StartPointOf lineSegment
  -> Const EndPointType (StartPointOf lineSegment))
 -> lineSegment -> Const EndPointType lineSegment)
-> ((EndPointType -> Const EndPointType EndPointType)
    -> StartPointOf lineSegment
    -> Const EndPointType (StartPointOf lineSegment))
-> Getting EndPointType lineSegment EndPointType
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(StartPointOf lineSegment -> EndPointType)
-> (EndPointType -> Const EndPointType EndPointType)
-> StartPointOf lineSegment
-> Const EndPointType (StartPointOf lineSegment)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to StartPointOf lineSegment -> EndPointType
forall endPoint. EndPoint_ endPoint => endPoint -> EndPointType
endPointType) (point -> LinePV 2 r -> SideTest
forall r point.
(Ord r, Num r, Point_ point 2 r) =>
point -> LinePV 2 r -> SideTest
onSide point
q LinePV 2 r
l) SideTest
LeftSide
    Bool -> Bool -> Bool
&& EndPointType -> SideTest -> SideTest -> Bool
shouldBe (lineSegment
seglineSegment
-> Getting EndPointType lineSegment EndPointType -> EndPointType
forall s a. s -> Getting a s a -> a
^.(EndPointOf lineSegment
 -> Const EndPointType (EndPointOf lineSegment))
-> lineSegment -> Const EndPointType lineSegment
forall seg p. HasEndPoint seg p => Lens' seg p
Lens' lineSegment (EndPointOf lineSegment)
endPoint((EndPointOf lineSegment
  -> Const EndPointType (EndPointOf lineSegment))
 -> lineSegment -> Const EndPointType lineSegment)
-> ((EndPointType -> Const EndPointType EndPointType)
    -> EndPointOf lineSegment
    -> Const EndPointType (EndPointOf lineSegment))
-> Getting EndPointType lineSegment EndPointType
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(EndPointOf lineSegment -> EndPointType)
-> (EndPointType -> Const EndPointType EndPointType)
-> EndPointOf lineSegment
-> Const EndPointType (EndPointOf lineSegment)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to EndPointOf lineSegment -> EndPointType
forall endPoint. EndPoint_ endPoint => endPoint -> EndPointType
endPointType)   (point -> LinePV 2 r -> SideTest
forall r point.
(Ord r, Num r, Point_ point 2 r) =>
point -> LinePV 2 r -> SideTest
onSide point
q LinePV 2 r
r) SideTest
RightSide
  where
    supLine :: LinePV 2 r
supLine = Point 2 r -> Vector 2 r -> LinePV 2 r
forall (d :: Nat) r. Point d r -> Vector d r -> LinePV d r
LinePV (point'
spoint' -> Getting (Point 2 r) point' (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.Getting (Point 2 r) point' (Point 2 r)
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point' (Point 2 r)
asPoint) (point'
t point' -> point' -> Vector 2 r
forall point (d :: Nat) r.
(Affine_ point d r, Num r) =>
point -> point -> Vector d r
.-. point'
s)
    l :: LinePV 2 r
l = LinePV 2 r -> LinePV 2 r
forall r. Num r => LinePV 2 r -> LinePV 2 r
perpendicularTo LinePV 2 r
supLine
    r :: LinePV 2 r
r = LinePV 2 r -> LinePV 2 r
forall r. Num r => LinePV 2 r -> LinePV 2 r
perpendicularTo (LinePV 2 r -> LinePV 2 r) -> LinePV 2 r -> 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 (point'
tpoint' -> Getting (Point 2 r) point' (Point 2 r) -> Point 2 r
forall s a. s -> Getting a s a -> a
^.Getting (Point 2 r) point' (Point 2 r)
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point' (Point 2 r)
asPoint) (point'
t point' -> point' -> Vector 2 r
forall point (d :: Nat) r.
(Affine_ point d r, Num r) =>
point -> point -> Vector d r
.-. point'
s)

    -- shouldBe t a side is essentially a == side, but in case the type is open
    -- we alos allow to be on the line.
    shouldBe :: EndPointType -> SideTest -> SideTest -> Bool
shouldBe EndPointType
et SideTest
a SideTest
side = case EndPointType
et of
      EndPointType
Open   -> SideTest
a SideTest -> SideTest -> Bool
forall a. Eq a => a -> a -> Bool
== SideTest
side
      EndPointType
Closed -> SideTest
a SideTest -> SideTest -> Bool
forall a. Eq a => a -> a -> Bool
== SideTest
side Bool -> Bool -> Bool
|| SideTest
a SideTest -> SideTest -> Bool
forall a. Eq a => a -> a -> Bool
== SideTest
OnLine



instance {-# OVERLAPPING #-} ( Point_ point 2 r, Num r
         ) => HasOnSegment (ClosedLineSegment point) 2 where
  onSegment :: forall r point.
(Ord r, Point_ point 2 r, r ~ NumType (ClosedLineSegment point),
 2 ~ Dimension (ClosedLineSegment point)) =>
point -> ClosedLineSegment point -> Bool
onSegment = point -> ClosedLineSegment point -> Bool
forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onSegment2
instance {-# OVERLAPPING #-} ( Point_ point 2 r, Num r
         ) => HasOnSegment (OpenLineSegment point) 2 where
  onSegment :: forall r point.
(Ord r, Point_ point 2 r, r ~ NumType (OpenLineSegment point),
 2 ~ Dimension (OpenLineSegment point)) =>
point -> OpenLineSegment point -> Bool
onSegment = point -> OpenLineSegment point -> Bool
forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onSegment2
instance {-# OVERLAPPING #-} ( Point_ point 2 r, Num r
         ) => HasOnSegment (LineSegment AnEndPoint point) 2 where
  onSegment :: forall r point.
(Ord r, Point_ point 2 r,
 r ~ NumType (LineSegment AnEndPoint point),
 2 ~ Dimension (LineSegment AnEndPoint point)) =>
point -> LineSegment AnEndPoint point -> Bool
onSegment = point -> LineSegment AnEndPoint point -> Bool
forall point r point' lineSegment.
(Point_ point 2 r, Point_ point' 2 r, Ord r, Num r,
 LineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onSegment2

instance ( Point_ point d r, Fractional r) => HasOnSegment (ClosedLineSegment point) d where
  onSegment :: forall r point.
(Ord r, Point_ point d r, r ~ NumType (ClosedLineSegment point),
 d ~ Dimension (ClosedLineSegment point)) =>
point -> ClosedLineSegment point -> Bool
onSegment = point -> ClosedLineSegment point -> Bool
forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r,
 ClosedLineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onClosedSegmentD

instance ( Point_ point d r, Fractional r) => HasOnSegment (OpenLineSegment point) d where
  onSegment :: forall r point.
(Ord r, Point_ point d r, r ~ NumType (OpenLineSegment point),
 d ~ Dimension (OpenLineSegment point)) =>
point -> OpenLineSegment point -> Bool
onSegment = point -> OpenLineSegment point -> Bool
forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r,
 OpenLineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onOpenSegmentD

instance ( Point_ point d r, Fractional r) => HasOnSegment (LineSegment AnEndPoint point) d where
  onSegment :: forall r point.
(Ord r, Point_ point d r,
 r ~ NumType (LineSegment AnEndPoint point),
 d ~ Dimension (LineSegment AnEndPoint point)) =>
point -> LineSegment AnEndPoint point -> Bool
onSegment = point -> LineSegment AnEndPoint point -> Bool
forall point (d :: Nat) r point'.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r) =>
point -> LineSegment AnEndPoint point' -> Bool
onSegmentD

-- | Implementation of onSegment for d-dimensional segments. The function should
onSegmentDWith                           :: ( Point_ point d r
                                            , Point_ point' d r
                                            , LineSegment_ lineSegment point'
                                            , Fractional r, Eq r
                                            )
                                         => (r -> Bool)
                                         -> point -> lineSegment -> Bool
onSegmentDWith :: forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r,
 LineSegment_ lineSegment point', Fractional r, Eq r) =>
(r -> Bool) -> point -> lineSegment -> Bool
onSegmentDWith r -> Bool
f (Getting (Point d r) point (Point d r) -> point -> Point d r
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Point d r) point (Point d r)
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point (Point d r)
asPoint -> Point d r
q) lineSegment
seg = Bool -> (r -> Bool) -> Maybe r -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False r -> Bool
f Maybe r
mLambda
  where
    mLambda :: Maybe r
mLambda = (Point d r
q Point d r -> Point d r -> Vector d r
forall point (d :: Nat) r.
(Affine_ point d r, Num r) =>
point -> point -> Vector d r
.-. (lineSegment
seglineSegment
-> Getting (Point d r) lineSegment (Point d r) -> Point d r
forall s a. s -> Getting a s a -> a
^.(point' -> Const (Point d r) point')
-> lineSegment -> Const (Point d r) lineSegment
forall seg p. HasStart seg p => Lens' seg p
Lens' lineSegment point'
start((point' -> Const (Point d r) point')
 -> lineSegment -> Const (Point d r) lineSegment)
-> ((Point d r -> Const (Point d r) (Point d r))
    -> point' -> Const (Point d r) point')
-> Getting (Point d r) lineSegment (Point d r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Point d r -> Const (Point d r) (Point d r))
-> point' -> Const (Point d r) point'
forall point (d :: Nat) r.
Point_ point d r =>
Lens' point (Point d r)
Lens' point' (Point d r)
asPoint)) Vector d r -> Vector d r -> Maybe r
forall r vector (d :: Nat).
(Eq r, Fractional r, Additive_ vector d r) =>
vector -> vector -> Maybe r
`scalarMultiple` ((lineSegment
seglineSegment -> Getting point' lineSegment point' -> point'
forall s a. s -> Getting a s a -> a
^.Getting point' lineSegment point'
forall seg p. HasEnd seg p => Lens' seg p
Lens' lineSegment point'
end) point' -> point' -> Vector d r
forall point (d :: Nat) r.
(Affine_ point d r, Num r) =>
point -> point -> Vector d r
.-. (lineSegment
seglineSegment -> Getting point' lineSegment point' -> point'
forall s a. s -> Getting a s a -> a
^.Getting point' lineSegment point'
forall seg p. HasStart seg p => Lens' seg p
Lens' lineSegment point'
start))

onClosedSegmentD :: ( Point_ point d r, Point_ point' d r, Fractional r, Ord r
                    , ClosedLineSegment_ lineSegment point'
                    ) => point -> lineSegment -> Bool
onClosedSegmentD :: forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r,
 ClosedLineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onClosedSegmentD = (r -> Bool) -> point -> lineSegment -> Bool
forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r,
 LineSegment_ lineSegment point', Fractional r, Eq r) =>
(r -> Bool) -> point -> lineSegment -> Bool
onSegmentDWith ((r -> Bool) -> point -> lineSegment -> Bool)
-> (r -> Bool) -> point -> lineSegment -> Bool
forall a b. (a -> b) -> a -> b
$ \r
lambda -> r
0 r -> r -> Bool
forall a. Ord a => a -> a -> Bool
<= r
lambda Bool -> Bool -> Bool
&& r
lambda r -> r -> Bool
forall a. Ord a => a -> a -> Bool
<= r
1

onOpenSegmentD :: ( Point_ point d r, Point_ point' d r, Fractional r, Ord r
                  , OpenLineSegment_ lineSegment point'
                  ) => point -> lineSegment -> Bool
onOpenSegmentD :: forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r,
 OpenLineSegment_ lineSegment point') =>
point -> lineSegment -> Bool
onOpenSegmentD = (r -> Bool) -> point -> lineSegment -> Bool
forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r,
 LineSegment_ lineSegment point', Fractional r, Eq r) =>
(r -> Bool) -> point -> lineSegment -> Bool
onSegmentDWith ((r -> Bool) -> point -> lineSegment -> Bool)
-> (r -> Bool) -> point -> lineSegment -> Bool
forall a b. (a -> b) -> a -> b
$ \r
lambda -> r
0 r -> r -> Bool
forall a. Ord a => a -> a -> Bool
< r
lambda Bool -> Bool -> Bool
&& r
lambda r -> r -> Bool
forall a. Ord a => a -> a -> Bool
< r
1

onSegmentD      :: ( Point_ point d r, Point_ point' d r, Fractional r, Ord r
                   ) => point -> LineSegment AnEndPoint point' -> Bool
onSegmentD :: forall point (d :: Nat) r point'.
(Point_ point d r, Point_ point' d r, Fractional r, Ord r) =>
point -> LineSegment AnEndPoint point' -> Bool
onSegmentD point
q LineSegment AnEndPoint point'
seg = (r -> Bool) -> point -> LineSegment AnEndPoint point' -> Bool
forall point (d :: Nat) r point' lineSegment.
(Point_ point d r, Point_ point' d r,
 LineSegment_ lineSegment point', Fractional r, Eq r) =>
(r -> Bool) -> point -> lineSegment -> Bool
onSegmentDWith r -> Bool
f point
q LineSegment AnEndPoint point'
seg
  where
    f :: r -> Bool
f r
lambda = EndPointType -> r -> r -> Bool
compare' (LineSegment AnEndPoint point'
segLineSegment AnEndPoint point'
-> Getting
     EndPointType (LineSegment AnEndPoint point') EndPointType
-> EndPointType
forall s a. s -> Getting a s a -> a
^.(AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
-> LineSegment AnEndPoint point'
-> Const EndPointType (LineSegment AnEndPoint point')
forall seg p. HasStartPoint seg p => Lens' seg p
Lens' (LineSegment AnEndPoint point') (AnEndPoint point')
startPoint((AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
 -> LineSegment AnEndPoint point'
 -> Const EndPointType (LineSegment AnEndPoint point'))
-> ((EndPointType -> Const EndPointType EndPointType)
    -> AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
-> Getting
     EndPointType (LineSegment AnEndPoint point') EndPointType
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(AnEndPoint point' -> EndPointType)
-> (EndPointType -> Const EndPointType EndPointType)
-> AnEndPoint point'
-> Const EndPointType (AnEndPoint point')
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to AnEndPoint point' -> EndPointType
forall endPoint. EndPoint_ endPoint => endPoint -> EndPointType
endPointType) r
0      r
lambda
            Bool -> Bool -> Bool
&& EndPointType -> r -> r -> Bool
compare' (LineSegment AnEndPoint point'
segLineSegment AnEndPoint point'
-> Getting
     EndPointType (LineSegment AnEndPoint point') EndPointType
-> EndPointType
forall s a. s -> Getting a s a -> a
^.(AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
-> LineSegment AnEndPoint point'
-> Const EndPointType (LineSegment AnEndPoint point')
forall seg p. HasEndPoint seg p => Lens' seg p
Lens' (LineSegment AnEndPoint point') (AnEndPoint point')
endPoint((AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
 -> LineSegment AnEndPoint point'
 -> Const EndPointType (LineSegment AnEndPoint point'))
-> ((EndPointType -> Const EndPointType EndPointType)
    -> AnEndPoint point' -> Const EndPointType (AnEndPoint point'))
-> Getting
     EndPointType (LineSegment AnEndPoint point') EndPointType
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(AnEndPoint point' -> EndPointType)
-> (EndPointType -> Const EndPointType EndPointType)
-> AnEndPoint point'
-> Const EndPointType (AnEndPoint point')
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to AnEndPoint point' -> EndPointType
forall endPoint. EndPoint_ endPoint => endPoint -> EndPointType
endPointType)   r
lambda r
1
    compare' :: EndPointType -> r -> r -> Bool
compare' = \case
      EndPointType
Open   -> r -> r -> Bool
forall a. Ord a => a -> a -> Bool
(<)
      EndPointType
Closed -> r -> r -> Bool
forall a. Ord a => a -> a -> Bool
(<=)


instance ( Point_ point d r
         , IxValue (endPoint point) ~ point
         , EndPoint_ (endPoint point)
         , IsTransformable point
         ) => IsTransformable (LineSegment endPoint point) where
  transformBy :: Transformation
  (Dimension (LineSegment endPoint point))
  (NumType (LineSegment endPoint point))
-> LineSegment endPoint point -> LineSegment endPoint point
transformBy Transformation
  (Dimension (LineSegment endPoint point))
  (NumType (LineSegment endPoint point))
t LineSegment endPoint point
s = LineSegment endPoint point
sLineSegment endPoint point
-> (LineSegment endPoint point -> LineSegment endPoint point)
-> LineSegment endPoint point
forall a b. a -> (a -> b) -> b
&(point -> Identity point)
-> LineSegment endPoint point
-> Identity (LineSegment endPoint point)
forall seg p. HasStart seg p => Lens' seg p
Lens' (LineSegment endPoint point) point
start ((point -> Identity point)
 -> LineSegment endPoint point
 -> Identity (LineSegment endPoint point))
-> (point -> point)
-> LineSegment endPoint point
-> LineSegment endPoint point
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Transformation (Dimension point) (NumType point) -> point -> point
forall g.
IsTransformable g =>
Transformation (Dimension g) (NumType g) -> g -> g
transformBy Transformation (Dimension point) (NumType point)
Transformation
  (Dimension (LineSegment endPoint point))
  (NumType (LineSegment endPoint point))
t
                     LineSegment endPoint point
-> (LineSegment endPoint point -> LineSegment endPoint point)
-> LineSegment endPoint point
forall a b. a -> (a -> b) -> b
&(point -> Identity point)
-> LineSegment endPoint point
-> Identity (LineSegment endPoint point)
forall seg p. HasEnd seg p => Lens' seg p
Lens' (LineSegment endPoint point) point
end   ((point -> Identity point)
 -> LineSegment endPoint point
 -> Identity (LineSegment endPoint point))
-> (point -> point)
-> LineSegment endPoint point
-> LineSegment endPoint point
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Transformation (Dimension point) (NumType point) -> point -> point
forall g.
IsTransformable g =>
Transformation (Dimension g) (NumType g) -> g -> g
transformBy Transformation (Dimension point) (NumType point)
Transformation
  (Dimension (LineSegment endPoint point))
  (NumType (LineSegment endPoint point))
t



-- | Data type modelling the index type for Line Segments
data StartEnd = Start | End
  deriving (Int -> StartEnd -> ShowS
[StartEnd] -> ShowS
StartEnd -> String
(Int -> StartEnd -> ShowS)
-> (StartEnd -> String) -> ([StartEnd] -> ShowS) -> Show StartEnd
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StartEnd -> ShowS
showsPrec :: Int -> StartEnd -> ShowS
$cshow :: StartEnd -> String
show :: StartEnd -> String
$cshowList :: [StartEnd] -> ShowS
showList :: [StartEnd] -> ShowS
Show,StartEnd -> StartEnd -> Bool
(StartEnd -> StartEnd -> Bool)
-> (StartEnd -> StartEnd -> Bool) -> Eq StartEnd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StartEnd -> StartEnd -> Bool
== :: StartEnd -> StartEnd -> Bool
$c/= :: StartEnd -> StartEnd -> Bool
/= :: StartEnd -> StartEnd -> Bool
Eq,Eq StartEnd
Eq StartEnd =>
(StartEnd -> StartEnd -> Ordering)
-> (StartEnd -> StartEnd -> Bool)
-> (StartEnd -> StartEnd -> Bool)
-> (StartEnd -> StartEnd -> Bool)
-> (StartEnd -> StartEnd -> Bool)
-> (StartEnd -> StartEnd -> StartEnd)
-> (StartEnd -> StartEnd -> StartEnd)
-> Ord StartEnd
StartEnd -> StartEnd -> Bool
StartEnd -> StartEnd -> Ordering
StartEnd -> StartEnd -> StartEnd
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
$ccompare :: StartEnd -> StartEnd -> Ordering
compare :: StartEnd -> StartEnd -> Ordering
$c< :: StartEnd -> StartEnd -> Bool
< :: StartEnd -> StartEnd -> Bool
$c<= :: StartEnd -> StartEnd -> Bool
<= :: StartEnd -> StartEnd -> Bool
$c> :: StartEnd -> StartEnd -> Bool
> :: StartEnd -> StartEnd -> Bool
$c>= :: StartEnd -> StartEnd -> Bool
>= :: StartEnd -> StartEnd -> Bool
$cmax :: StartEnd -> StartEnd -> StartEnd
max :: StartEnd -> StartEnd -> StartEnd
$cmin :: StartEnd -> StartEnd -> StartEnd
min :: StartEnd -> StartEnd -> StartEnd
Ord)

instance ( IxValue (endPoint vertex) ~ vertex, EndPoint_ (endPoint vertex)
         ) => HasVertices' (LineSegment endPoint vertex) where
  type Vertex   (LineSegment endPoint vertex) = vertex
  type VertexIx (LineSegment endPoint vertex) = StartEnd
  vertexAt :: VertexIx (LineSegment endPoint vertex)
-> IndexedTraversal'
     (VertexIx (LineSegment endPoint vertex))
     (LineSegment endPoint vertex)
     (Vertex (LineSegment endPoint vertex))
vertexAt = \case
    VertexIx (LineSegment endPoint vertex)
StartEnd
Start -> \p (Vertex (LineSegment endPoint vertex))
  (f (Vertex (LineSegment endPoint vertex)))
paFa -> (vertex -> f vertex)
-> LineSegment endPoint vertex -> f (LineSegment endPoint vertex)
forall seg p. HasStart seg p => Lens' seg p
Lens' (LineSegment endPoint vertex) vertex
start (p vertex (f vertex) -> StartEnd -> vertex -> f vertex
forall a b. p a b -> StartEnd -> a -> b
forall i (p :: * -> * -> *) a b.
Indexable i p =>
p a b -> i -> a -> b
indexed p vertex (f vertex)
p (Vertex (LineSegment endPoint vertex))
  (f (Vertex (LineSegment endPoint vertex)))
paFa StartEnd
Start)
    VertexIx (LineSegment endPoint vertex)
StartEnd
End   -> \p (Vertex (LineSegment endPoint vertex))
  (f (Vertex (LineSegment endPoint vertex)))
paFa -> (vertex -> f vertex)
-> LineSegment endPoint vertex -> f (LineSegment endPoint vertex)
forall seg p. HasEnd seg p => Lens' seg p
Lens' (LineSegment endPoint vertex) vertex
end   (p vertex (f vertex) -> StartEnd -> vertex -> f vertex
forall a b. p a b -> StartEnd -> a -> b
forall i (p :: * -> * -> *) a b.
Indexable i p =>
p a b -> i -> a -> b
indexed p vertex (f vertex)
p (Vertex (LineSegment endPoint vertex))
  (f (Vertex (LineSegment endPoint vertex)))
paFa StartEnd
End)
  {-# INLINE vertexAt #-}
  numVertices :: LineSegment endPoint vertex -> Int
numVertices = Int -> LineSegment endPoint vertex -> Int
forall a b. a -> b -> a
const Int
2

instance ( Traversable1 endPoint, EndPoint_ (endPoint v)
         , IxValue (endPoint v) ~ v
         )
           => HasVertices (LineSegment endPoint v) (LineSegment endPoint v') where
  vertices :: IndexedTraversal1
  (VertexIx (LineSegment endPoint v))
  (LineSegment endPoint v)
  (LineSegment endPoint v')
  (Vertex (LineSegment endPoint v))
  (Vertex (LineSegment endPoint v'))
vertices = ((p ~ (->)) =>
 (v -> f v')
 -> LineSegment endPoint v -> f (LineSegment endPoint v'))
-> (p v (f v')
    -> LineSegment endPoint v -> f (LineSegment endPoint v'))
-> p v (f v')
-> LineSegment endPoint v
-> f (LineSegment endPoint v')
forall (p :: * -> * -> *) (q :: * -> * -> *) a b r.
Conjoined p =>
((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
forall (q :: * -> * -> *) a b r.
((p ~ (->)) => q (a -> b) r) -> q (p a b) r -> q (p a b) r
conjoined (p ~ (->)) =>
(v -> f v')
-> LineSegment endPoint v -> f (LineSegment endPoint v')
(v -> f v')
-> LineSegment endPoint v -> f (LineSegment endPoint v')
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> LineSegment endPoint a -> f (LineSegment endPoint b)
traverse1 ((StartEnd -> v -> f v')
-> LineSegment endPoint v -> f (LineSegment endPoint v')
forall {endPoint :: * -> *} {f :: * -> *} {a} {point}.
(Traversable1 endPoint, Apply f) =>
(StartEnd -> a -> f point)
-> LineSegment endPoint a -> f (LineSegment endPoint point)
itrav((StartEnd -> v -> f v')
 -> LineSegment endPoint v -> f (LineSegment endPoint v'))
-> (p v (f v') -> StartEnd -> v -> f v')
-> p v (f v')
-> LineSegment endPoint v
-> f (LineSegment endPoint v')
forall b c a. (b -> c) -> (a -> b) -> a -> c
.p v (f v') -> StartEnd -> v -> f v'
forall a b. p a b -> StartEnd -> a -> b
forall i (p :: * -> * -> *) a b.
Indexable i p =>
p a b -> i -> a -> b
indexed)
    where
      itrav :: (StartEnd -> a -> f point)
-> LineSegment endPoint a -> f (LineSegment endPoint point)
itrav StartEnd -> a -> f point
f (LineSegment endPoint a
s endPoint a
t) =
        endPoint point -> endPoint point -> LineSegment endPoint point
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment (endPoint point -> endPoint point -> LineSegment endPoint point)
-> f (endPoint point)
-> f (endPoint point -> LineSegment endPoint point)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f point) -> endPoint a -> f (endPoint point)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 (StartEnd -> a -> f point
f StartEnd
Start) endPoint a
s f (endPoint point -> LineSegment endPoint point)
-> f (endPoint point) -> f (LineSegment endPoint point)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Apply f => f (a -> b) -> f a -> f b
Apply.<.> (a -> f point) -> endPoint a -> f (endPoint point)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> endPoint a -> f (endPoint b)
traverse1 (StartEnd -> a -> f point
f StartEnd
End) endPoint a
t
  {-# INLINE vertices #-}




  -- traverse1' f xs =
  --     -- Get the length of the vector in /O(1)/ time
  --     let !n = G.length xs
  --     -- Use fromListN to be more efficient in construction of resulting vector
  --     -- Also behaves better with compact regions, preventing runtime exceptions
  --     in  Data.Vector.fromListN n Applicative.<$> Traversable.traverse f (toList xs<)


-- type R = RealNumber 5

-- intersects2 :: Point 2 R -> ClosedLineSegment (Point 2 R) -> Bool
-- intersects2 = intersects

-- testseg1 :: ClosedLineSegment (Point 2 R)
-- testseg1 = ClosedLineSegment (Point2 5.0 6.0) (Point2 10.0 10.0)

-- myPoint :: Point 2 R
-- myPoint = Point2 11 11


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

-- | Computes the span of the interval in the given direction. Note that the returned
-- interval is a proper interval, i.e. with the start smaller than the end.
--
-- >>> spanIn xCoord (ClosedLineSegment (Point2 5 (10 :: Int)) (Point2 20 0))
-- Interval (AnEndPoint Closed 5) (AnEndPoint Closed 20)
-- >>> spanIn yCoord (ClosedLineSegment (Point2 5 (10 :: Int)) (Point2 20 0))
-- Interval (AnEndPoint Closed 0) (AnEndPoint Closed 10)
spanIn             :: ( Point_ point d r, Ord r
                      , IxValue (endPoint point) ~ point
                      -- , EndPoint_ (endPoint r)
                      , EndPoint_ (endPoint point)
                      )
                   => Getter point r
                   -> LineSegment endPoint point
                   -> Interval AnEndPoint r
spanIn :: forall point (d :: Nat) r (endPoint :: * -> *).
(Point_ point d r, Ord r, IxValue (endPoint point) ~ point,
 EndPoint_ (endPoint point)) =>
Getter point r
-> LineSegment endPoint point -> Interval AnEndPoint r
spanIn Getter point r
coord'' LineSegment endPoint point
seg = case (Interval AnEndPoint r
iInterval AnEndPoint r -> Getting r (Interval AnEndPoint r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (Interval AnEndPoint r) r
forall seg p. HasStart seg p => Lens' seg p
Lens' (Interval AnEndPoint r) r
start) r -> r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` (Interval AnEndPoint r
iInterval AnEndPoint r -> Getting r (Interval AnEndPoint r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (Interval AnEndPoint r) r
forall seg p. HasEnd seg p => Lens' seg p
Lens' (Interval AnEndPoint r) r
end) of
                       Ordering
LT -> Interval AnEndPoint r
i
                       Ordering
EQ -> AnEndPoint r -> AnEndPoint r -> Interval AnEndPoint r
forall {k} (endPoint :: k -> *) (r :: k).
endPoint r -> endPoint r -> Interval endPoint r
Interval (r -> AnEndPoint r
forall r. r -> AnEndPoint r
AnClosedE (AnEndPoint r
sAnEndPoint r -> Getting r (AnEndPoint r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (AnEndPoint r) r
(IxValue (AnEndPoint r) -> Const r (IxValue (AnEndPoint r)))
-> AnEndPoint r -> Const r (AnEndPoint r)
forall endPoint endPoint'.
IsEndPoint endPoint endPoint' =>
Lens endPoint endPoint' (IxValue endPoint) (IxValue endPoint')
Lens
  (AnEndPoint r)
  (AnEndPoint r)
  (IxValue (AnEndPoint r))
  (IxValue (AnEndPoint r))
_endPoint)) (r -> AnEndPoint r
forall r. r -> AnEndPoint r
AnClosedE (AnEndPoint r
eAnEndPoint r -> Getting r (AnEndPoint r) r -> r
forall s a. s -> Getting a s a -> a
^.Getting r (AnEndPoint r) r
(IxValue (AnEndPoint r) -> Const r (IxValue (AnEndPoint r)))
-> AnEndPoint r -> Const r (AnEndPoint r)
forall endPoint endPoint'.
IsEndPoint endPoint endPoint' =>
Lens endPoint endPoint' (IxValue endPoint) (IxValue endPoint')
Lens
  (AnEndPoint r)
  (AnEndPoint r)
  (IxValue (AnEndPoint r))
  (IxValue (AnEndPoint r))
_endPoint))
                       Ordering
GT -> AnEndPoint r -> AnEndPoint r -> Interval AnEndPoint r
forall {k} (endPoint :: k -> *) (r :: k).
endPoint r -> endPoint r -> Interval endPoint r
Interval AnEndPoint r
e AnEndPoint r
s
  where
    i :: Interval AnEndPoint r
i@(Interval AnEndPoint r
s AnEndPoint r
e) = Getting r point r -> point -> r
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting r point r
Getter point r
coord'' (point -> r) -> Interval AnEndPoint point -> Interval AnEndPoint r
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LineSegment endPoint point
segLineSegment endPoint point
-> Getting
     (Interval AnEndPoint point)
     (LineSegment endPoint point)
     (Interval AnEndPoint point)
-> Interval AnEndPoint point
forall s a. s -> Getting a s a -> a
^.(Interval endPoint point
 -> Const (Interval AnEndPoint point) (Interval endPoint point))
-> LineSegment endPoint point
-> Const (Interval AnEndPoint point) (LineSegment endPoint point)
forall (endPoint :: * -> *) point (endPoint' :: * -> *) point'
       (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Functor f) =>
p (Interval endPoint point) (f (Interval endPoint' point'))
-> p (LineSegment endPoint point)
     (f (LineSegment endPoint' point'))
_LineSegmentInterval((Interval endPoint point
  -> Const (Interval AnEndPoint point) (Interval endPoint point))
 -> LineSegment endPoint point
 -> Const (Interval AnEndPoint point) (LineSegment endPoint point))
-> ((Interval AnEndPoint point
     -> Const (Interval AnEndPoint point) (Interval AnEndPoint point))
    -> Interval endPoint point
    -> Const (Interval AnEndPoint point) (Interval endPoint point))
-> Getting
     (Interval AnEndPoint point)
     (LineSegment endPoint point)
     (Interval AnEndPoint point)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Interval endPoint point -> Interval AnEndPoint point)
-> (Interval AnEndPoint point
    -> Const (Interval AnEndPoint point) (Interval AnEndPoint point))
-> Interval endPoint point
-> Const (Interval AnEndPoint point) (Interval endPoint point)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Interval endPoint point -> Interval AnEndPoint point
forall interval r.
Interval_ interval r =>
interval -> Interval AnEndPoint r
asAnInterval


-- | convert into an LineSegment whose endpoints are explicitly tagged.
asALineSegment   :: LineSegment_ segment point => segment -> LineSegment AnEndPoint point
asALineSegment :: forall segment point.
LineSegment_ segment point =>
segment -> LineSegment AnEndPoint point
asALineSegment segment
e = AnEndPoint point
-> AnEndPoint point -> LineSegment AnEndPoint point
forall (endPoint :: * -> *) point.
endPoint point -> endPoint point -> LineSegment endPoint point
LineSegment (StartPointOf segment -> AnEndPoint (IxValue (StartPointOf segment))
forall endPoint.
EndPoint_ endPoint =>
endPoint -> AnEndPoint (IxValue endPoint)
asAnEndPoint (StartPointOf segment
 -> AnEndPoint (IxValue (StartPointOf segment)))
-> StartPointOf segment
-> AnEndPoint (IxValue (StartPointOf segment))
forall a b. (a -> b) -> a -> b
$ segment
esegment
-> Getting (StartPointOf segment) segment (StartPointOf segment)
-> StartPointOf segment
forall s a. s -> Getting a s a -> a
^.Getting (StartPointOf segment) segment (StartPointOf segment)
forall seg p. HasStartPoint seg p => Lens' seg p
Lens' segment (StartPointOf segment)
startPoint) (EndPointOf segment -> AnEndPoint (IxValue (EndPointOf segment))
forall endPoint.
EndPoint_ endPoint =>
endPoint -> AnEndPoint (IxValue endPoint)
asAnEndPoint (EndPointOf segment -> AnEndPoint (IxValue (EndPointOf segment)))
-> EndPointOf segment -> AnEndPoint (IxValue (EndPointOf segment))
forall a b. (a -> b) -> a -> b
$ segment
esegment
-> Getting (EndPointOf segment) segment (EndPointOf segment)
-> EndPointOf segment
forall s a. s -> Getting a s a -> a
^.Getting (EndPointOf segment) segment (EndPointOf segment)
forall seg p. HasEndPoint seg p => Lens' seg p
Lens' segment (EndPointOf segment)
endPoint)