{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Geometry.LineSegment
( LineSegment(LineSegment, LineSegment', ClosedLineSegment, OpenLineSegment)
, endPoints
, _SubLine
, module Data.Geometry.Interval
, toLineSegment
, orderedEndPoints
, segmentLength
, sqSegmentLength
, sqDistanceToSeg, sqDistanceToSegArg
, flipSegment
, interpolate, sampleLineSegment
, ordAtX, ordAtY, xCoordAt, yCoordAt
) where
import Data.Ext
import Data.Geometry.Boundary
import Data.Geometry.Box.Internal
import Data.Geometry.Box.Sides
import Data.Geometry.Interval hiding (width, midPoint)
import Data.Geometry.LineSegment.Internal
import Data.Geometry.Point
import Data.Geometry.Properties
import Data.Util
type instance IntersectionOf (LineSegment 2 p r) (Boundary (Rectangle q r)) =
[ NoIntersection, Point 2 r, Two (Point 2 r) , LineSegment 2 () r ]
type instance IntersectionOf (LineSegment 2 p r) (Rectangle q r) =
[ NoIntersection, Point 2 r, LineSegment 2 (Maybe p) r ]
instance (Fractional r, Ord r)
=> LineSegment 2 p r `HasIntersectionWith` Boundary (Rectangle q r) where
LineSegment 2 p r
seg intersects :: LineSegment 2 p r -> Boundary (Rectangle q r) -> Bool
`intersects` (Boundary Rectangle q r
rect) = (LineSegment 2 q r -> Bool) -> Sides (LineSegment 2 q r) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (LineSegment 2 p r
seg LineSegment 2 p r -> LineSegment 2 q r -> Bool
forall g h. HasIntersectionWith g h => g -> h -> Bool
`intersects`) (Sides (LineSegment 2 q r) -> Bool)
-> Sides (LineSegment 2 q r) -> Bool
forall a b. (a -> b) -> a -> b
$ Rectangle q r -> Sides (LineSegment 2 q r)
forall r p. Num r => Rectangle p r -> Sides (LineSegment 2 p r)
sides Rectangle q r
rect
instance (Fractional r, Ord r) => LineSegment 2 p r `HasIntersectionWith` Rectangle q r where
seg :: LineSegment 2 p r
seg@(LineSegment EndPoint (Point 2 r :+ p)
p EndPoint (Point 2 r :+ p)
q) intersects :: LineSegment 2 p r -> Rectangle q r -> Bool
`intersects` Rectangle q r
rect =
EndPoint (Point 2 r :+ p) -> Bool
inRect EndPoint (Point 2 r :+ p)
p Bool -> Bool -> Bool
|| EndPoint (Point 2 r :+ p) -> Bool
inRect EndPoint (Point 2 r :+ p)
q Bool -> Bool -> Bool
|| (LineSegment 2 q r -> Bool) -> Sides (LineSegment 2 q r) -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (LineSegment 2 p r
seg LineSegment 2 p r -> LineSegment 2 q r -> Bool
forall g h. HasIntersectionWith g h => g -> h -> Bool
`intersects`) (Rectangle q r -> Sides (LineSegment 2 q r)
forall r p. Num r => Rectangle p r -> Sides (LineSegment 2 p r)
sides Rectangle q r
rect) Bool -> Bool -> Bool
|| LineSegment 2 p r -> Bool
bothOpenAndOnBoundary LineSegment 2 p r
seg
where
inRect :: EndPoint (Point 2 r :+ p) -> Bool
inRect = \case
Open (Point 2 r
a :+ p
_) -> Point 2 r
a Point 2 r -> Rectangle q r -> Bool
forall (d :: Nat) r p.
(Arity d, Ord r) =>
Point d r -> Box d p r -> Bool
`insideBox` Rectangle q r
rect
Closed (Point 2 r
a :+ p
_) -> Point 2 r
a Point 2 r -> Rectangle q r -> Bool
forall (d :: Nat) r p.
(Arity d, Ord r) =>
Point d r -> Box d p r -> Bool
`inBox` Rectangle q r
rect
bothOpenAndOnBoundary :: LineSegment 2 p r -> Bool
bothOpenAndOnBoundary (LineSegment (Open Point 2 r :+ p
_) (Open Point 2 r :+ p
_)) =
r -> LineSegment 2 p r -> Point 2 r
forall r (d :: Nat) p.
(Fractional r, Arity d) =>
r -> LineSegment d p r -> Point d r
interpolate (r
1r -> r -> r
forall a. Fractional a => a -> a -> a
/r
2) LineSegment 2 p r
seg Point 2 r -> Rectangle q r -> Bool
forall g h. HasIntersectionWith g h => g -> h -> Bool
`intersects` Rectangle q r
rect
bothOpenAndOnBoundary LineSegment 2 p r
_ = Bool
False