hgeometry-0.9.0.0: Geometric Algorithms, Data structures, and Data types.

Data.Geometry.Polygon

Contents

Description

A Polygon data type and some basic functions to interact with them.

Synopsis

# Polygons

>>> :{
-- import qualified Data.CircularSeq as C
let simplePoly :: SimplePolygon () Rational
simplePoly = SimplePolygon . C.fromList . map ext $[ point2 0 0 , point2 10 0 , point2 10 10 , point2 5 15 , point2 1 11 ] :}  We distinguish between simple polygons (without holes) and Polygons with holes. Constructors  Simple Multi data Polygon (t :: PolygonType) p r where Source # Constructors  SimplePolygon :: CSeq (Point 2 r :+ p) -> Polygon Simple p r MultiPolygon :: CSeq (Point 2 r :+ p) -> [Polygon Simple p r] -> Polygon Multi p r Instances  Source # Instance detailsDefined in Data.Geometry.Polygon Methodsbitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> Polygon t a b -> f (Polygon t c d) # Source # Instance detailsDefined in Data.Geometry.Polygon Methodsbifold :: Monoid m => Polygon t m m -> m #bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> Polygon t a b -> m #bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> Polygon t a b -> c #bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> Polygon t a b -> c # Source # Instance detailsDefined in Data.Geometry.Polygon Methodsbimap :: (a -> b) -> (c -> d) -> Polygon t a c -> Polygon t b d #first :: (a -> b) -> Polygon t a c -> Polygon t b c #second :: (b -> c) -> Polygon t a b -> Polygon t a c # PointFunctor (Polygon t p) Source # Instance detailsDefined in Data.Geometry.Polygon Methodspmap :: (Point (Dimension (Polygon t p r)) r -> Point (Dimension (Polygon t p s)) s) -> Polygon t p r -> Polygon t p s Source # (Fractional r, Ord r) => IsIntersectableWith (Point 2 r) (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon Methodsintersect :: Point 2 r -> Polygon t p r -> Intersection (Point 2 r) (Polygon t p r)intersects :: Point 2 r -> Polygon t p r -> BoolnonEmptyIntersection :: proxy (Point 2 r) -> proxy (Polygon t p r) -> Intersection (Point 2 r) (Polygon t p r) -> Bool (Eq p, Eq r) => Eq (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon Methods(==) :: Polygon t p r -> Polygon t p r -> Bool #(/=) :: Polygon t p r -> Polygon t p r -> Bool # (Show p, Show r) => Show (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon MethodsshowsPrec :: Int -> Polygon t p r -> ShowS #show :: Polygon t p r -> String #showList :: [Polygon t p r] -> ShowS # (NFData p, NFData r) => NFData (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon Methodsrnf :: Polygon t p r -> () # Fractional r => IsTransformable (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon MethodstransformBy :: Transformation (Dimension (Polygon t p r)) (NumType (Polygon t p r)) -> Polygon t p r -> Polygon t p r Source # IsBoxable (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon MethodsboundingBox :: Polygon t p r -> Box (Dimension (Polygon t p r)) () (NumType (Polygon t p r)) Source # type NumType (SomePolygon p r) Source # Instance detailsDefined in Data.Geometry.Polygon type NumType (SomePolygon p r) = r type Dimension (SomePolygon p r) Source # Instance detailsDefined in Data.Geometry.Polygon type Dimension (SomePolygon p r) = 2 type IntersectionOf (Line 2 r) (Boundary (Polygon t p r)) Source # Instance detailsDefined in Data.Geometry.Polygon type IntersectionOf (Line 2 r) (Boundary (Polygon t p r)) = Seq (Either (Point 2 r) (LineSegment 2 () r)) ': ([] :: [Type]) type IntersectionOf (Point 2 r) (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon type IntersectionOf (Point 2 r) (Polygon t p r) = NoIntersection ': (Point 2 r ': ([] :: [Type])) type NumType (Polygon t p r) Source # Instance detailsDefined in Data.Geometry.Polygon type NumType (Polygon t p r) = r type Dimension (Polygon t p r) Source # Polygons are per definition 2 dimensional Instance detailsDefined in Data.Geometry.Polygon type Dimension (Polygon t p r) = 2 bitraverseVertices :: (Applicative f, Traversable t) => (p -> f q) -> (r -> f s) -> t (Point 2 r :+ p) -> f (t (Point 2 s :+ q)) Source # type SomePolygon p r = Either (Polygon Simple p r) (Polygon Multi p r) Source # Either a simple or multipolygon # Functions on Polygons outerBoundary :: forall t p r. Lens' (Polygon t p r) (CSeq (Point 2 r :+ p)) Source # polygonHoles :: forall p r. Lens' (Polygon Multi p r) [Polygon Simple p r] Source # outerVertex :: Int -> Lens' (Polygon t p r) (Point 2 r :+ p) Source # Access the i^th vertex on the outer boundary holeList :: Polygon t p r -> [Polygon Simple p r] Source # Get all holes in a polygon polygonVertices :: Polygon t p r -> NonEmpty (Point 2 r :+ p) Source # The vertices in the polygon. No guarantees are given on the order in which they appear! fromPoints :: [Point 2 r :+ p] -> SimplePolygon p r Source # Creates a simple polygon from the given list of vertices. pre: the input list constains no repeated vertices. outerBoundaryEdges :: Polygon t p r -> CSeq (LineSegment 2 p r) Source # The edges along the outer boundary of the polygon. The edges are half open. running time: $$O(n)$$ listEdges :: Polygon t p r -> [LineSegment 2 p r] Source # Lists all edges. The edges on the outer boundary are given before the ones on the holes. However, no other guarantees are given on the order. running time: $$O(n)$$ withIncidentEdges :: Polygon t p r -> Polygon t (Two (LineSegment 2 p r)) r Source # Pairs every vertex with its incident edges. The first one is its predecessor edge, the second one its successor edge. >>> mapM_ print . polygonVertices$ withIncidentEdges simplePoly
Point2 [0 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ()))
Point2 [10 % 1,0 % 1] :+ SP LineSegment (Closed (Point2 [0 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,0 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ()))
Point2 [10 % 1,10 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,0 % 1] :+ ())) (Closed (Point2 [10 % 1,10 % 1] :+ ())) LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ()))
Point2 [5 % 1,15 % 1] :+ SP LineSegment (Closed (Point2 [10 % 1,10 % 1] :+ ())) (Closed (Point2 [5 % 1,15 % 1] :+ ())) LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ()))
Point2 [1 % 1,11 % 1] :+ SP LineSegment (Closed (Point2 [5 % 1,15 % 1] :+ ())) (Closed (Point2 [1 % 1,11 % 1] :+ ())) LineSegment (Closed (Point2 [1 % 1,11 % 1] :+ ())) (Closed (Point2 [0 % 1,0 % 1] :+ ()))


toEdges :: CSeq (Point 2 r :+ p) -> CSeq (LineSegment 2 p r) Source #

Given the vertices of the polygon. Produce a list of edges. The edges are half-open.

onBoundary :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool Source #

Test if q lies on the boundary of the polygon. Running time: O(n)

>>> point2 1 1 onBoundary simplePoly
False
>>> point2 0 0 onBoundary simplePoly
True
>>> point2 10 0 onBoundary simplePoly
True
>>> point2 5 13 onBoundary simplePoly
False
>>> point2 5 10 onBoundary simplePoly
False
>>> point2 10 5 onBoundary simplePoly
True
>>> point2 20 5 onBoundary simplePoly
False


TODO: testcases multipolygon

inPolygon :: forall t p r. (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> PointLocationResult Source #

Check if a point lies inside a polygon, on the boundary, or outside of the polygon. Running time: O(n).

>>> point2 1 1 inPolygon simplePoly
Inside
>>> point2 0 0 inPolygon simplePoly
OnBoundary
>>> point2 10 0 inPolygon simplePoly
OnBoundary
>>> point2 5 13 inPolygon simplePoly
Inside
>>> point2 5 10 inPolygon simplePoly
Inside
>>> point2 10 5 inPolygon simplePoly
OnBoundary
>>> point2 20 5 inPolygon simplePoly
Outside


TODO: Add some testcases with multiPolygons TODO: Add some more onBoundary testcases

insidePolygon :: (Fractional r, Ord r) => Point 2 r -> Polygon t p r -> Bool Source #

Test if a point lies strictly inside the polgyon.

area :: Fractional r => Polygon t p r -> r Source #

Compute the area of a polygon

signedArea :: Fractional r => SimplePolygon p r -> r Source #

Compute the signed area of a simple polygon. The the vertices are in clockwise order, the signed area will be negative, if the verices are given in counter clockwise order, the area will be positive.

centroid :: Fractional r => SimplePolygon p r -> Point 2 r Source #

Compute the centroid of a simple polygon.

pickPoint :: (Ord r, Fractional r) => Polygon p t r -> Point 2 r Source #

Pick a point that is inside the polygon.

(note: if the polygon is degenerate; i.e. has <3 vertices, we report a vertex of the polygon instead.)

pre: the polygon is given in CCW order

running time: $$O(n)$$

isTriangle :: Polygon p t r -> Bool Source #

Test if the polygon is a triangle

running time: $$O(1)$$

findDiagonal :: (Ord r, Fractional r) => Polygon t p r -> LineSegment 2 p r Source #

Find a diagonal of the polygon.

pre: the polygon is given in CCW order

running time: $$O(n)$$

safeMaximumOn :: Ord b => (a -> b) -> [a] -> Maybe a Source #

isCounterClockwise :: (Eq r, Fractional r) => Polygon t p r -> Bool Source #

Test if the outer boundary of the polygon is in clockwise or counter clockwise order.

running time: $$O(n)$$

toClockwiseOrder :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r Source #

Orient the outer boundary to clockwise order

toCounterClockWiseOrder :: (Eq r, Fractional r) => Polygon t p r -> Polygon t p r Source #

Orient the outer boundary to counter clockwise order

asSimplePolygon :: Polygon t p r -> SimplePolygon p r Source #

Convert a Polygon to a simple polygon by forgetting about any holes.

cmpExtreme :: (Num r, Ord r) => Vector 2 r -> (Point 2 r :+ p) -> (Point 2 r :+ q) -> Ordering Source #

Comparison that compares which point is larger in the direction given by the vector u.

extremesLinear :: (Ord r, Num r) => Vector 2 r -> Polygon t p r -> (Point 2 r :+ p, Point 2 r :+ p) Source #

Finds the extreme points, minimum and maximum, in a given direction

running time: $$O(n)$$

numberVertices :: Polygon t p r -> Polygon t (SP Int p) r Source #

assigns unique integer numbers to all vertices. Numbers start from 0, and are increasing along the outer boundary. The vertices of holes will be numbered last, in the same order.

>>> numberVertices simplePoly
SimplePolygon CSeq [Point2 [0 % 1,0 % 1] :+ SP 0 (),Point2 [10 % 1,0 % 1] :+ SP 1 (),Point2 [10 % 1,10 % 1] :+ SP 2 (),Point2 [5 % 1,15 % 1] :+ SP 3 (),Point2 [1 % 1,11 % 1] :+ SP 4 ()]


isStarShaped :: (MonadRandom m, Ord r, Fractional r) => SimplePolygon p r -> m (Maybe (Point 2 r)) Source #

Test if a Simple polygon is star-shaped. Returns a point in the kernel (i.e. from which the entire polygon is visible), if it exists.

$$O(n)$$ expected time