ianmackenzie / elm-geometry / Polygon2d

A Polygon2d represents a closed polygon in 2D, optionally with holes. It is defined by an outer loop of vertices and a list of inner loops defining any holes. This module contains a variety of polygon-related functionality, such as


type alias Polygon2d units coordinates =
Geometry.Types.Polygon2d units coordinates

Constructors

singleLoop : List (Point2d units coordinates) -> Polygon2d units coordinates

Construct a polygon without holes from a list of its vertices:

rectangle =
    Polygon2d.singleLoop
        [ Point2d.meters 1 1
        , Point2d.meters 3 1
        , Point2d.meters 3 2
        , Point2d.meters 1 2
        ]

The last vertex is implicitly considered to be connected back to the first vertex (you do not have to close the polygon explicitly). Vertices should ideally be provided in counterclockwise order; if they are provided in clockwise order they will be reversed.

withHoles : List (List (Point2d units coordinates)) -> List (Point2d units coordinates) -> Polygon2d units coordinates

Construct a polygon with holes from one outer loop and a list of inner loops. The loops must not touch or intersect each other.

outerLoop =
    [ Point2d.meters 0 0
    , Point2d.meters 3 0
    , Point2d.meters 3 3
    , Point2d.meters 0 3
    ]

innerLoop =
    [ Point2d.meters 1 1
    , Point2d.meters 1 2
    , Point2d.meters 2 2
    , Point2d.meters 2 1
    ]

squareWithHole =
    Polygon2d.withHoles [ innerLoop ] outerLoop

As with Polygon2d.singleLoop, the last vertex of each loop is considered to be connected back to the first. Vertices of the outer loop should ideally be provided in counterclockwise order and vertices of the inner loops should ideally be provided in clockwise order.

convexHull : List (Point2d units coordinates) -> Polygon2d units coordinates

Build the convex hull of a list of points:

Convex hull of a set of points

This is an O(n log n) operation.

regular : { centerPoint : Point2d units coordinates, circumradius : Quantity Basics.Float units, numSides : Basics.Int } -> Polygon2d units coordinates

Constructs a regular convex polygon with the specified center point, circumradius and number of sides. The polygon will be oriented so that the bottom edge is horizontal (assuming a Y-up coordinate system; note that SVG uses Y-down instead!).

Properties

outerLoop : Polygon2d units coordinates -> List (Point2d units coordinates)

Get the list of vertices definining the outer loop (border) of a polygon. The vertices will be in counterclockwise order.

Polygon2d.outerLoop squareWithHole
--> [ Point2d.meters 0 0
--> , Point2d.meters 3 0
--> , Point2d.meters 3 3
--> , Point2d.meters 0 3
--> ]

innerLoops : Polygon2d units coordinates -> List (List (Point2d units coordinates))

Get the holes (if any) of a polygon, each defined by a list of vertices. Each list of vertices will be in clockwise order.

Polygon2d.innerLoops squareWithHole
--> [ [ Point2d.meters 1 1
-->   , Point2d.meters 1 2
-->   , Point2d.meters 2 2
-->   , Point2d.meters 2 1
-->   ]
--> ]

vertices : Polygon2d units coordinates -> List (Point2d units coordinates)

Get all vertices of a polygon; this will include vertices from the outer loop of the polygon and all inner loops. The order of the returned vertices is undefined.

edges : Polygon2d units coordinates -> List (LineSegment2d units coordinates)

Get all edges of a polygon. This will include both outer edges and inner (hole) edges.

perimeter : Polygon2d units coordinates -> Quantity Basics.Float units

Get the perimeter of a polygon (the sum of the lengths of its edges). This includes the outer perimeter and the perimeter of any holes.

Polygon2d.perimeter squareWithHole
--> Length.meters 16

area : Polygon2d units coordinates -> Quantity Basics.Float (Quantity.Squared units)

Get the area of a polygon. This value will never be negative.

Polygon2d.area squareWithHole
--> Area.squareMeters 8

centroid : Polygon2d units coordinates -> Maybe (Point2d units coordinates)

Get the centroid of a polygon. Returns Nothing if the polygon has no vertices or zero area.

boundingBox : Polygon2d units coordinates -> Maybe (BoundingBox2d units coordinates)

Get the minimal bounding box containing a given polygon. Returns Nothing if the polygon has no vertices.

Polygon2d.boundingBox rectangle
--> Just <|
-->     BoundingBox2d.from
-->         (Point2d.meters 1 1)
-->         (Point2d.meters 3 2)

Queries

contains : Point2d units coordinates -> Polygon2d units coordinates -> Basics.Bool

Check if a polygon contains a given point.

This is an O(n) operation. The polygon can have holes and does not need to be convex.

Transformations

These transformations generally behave just like the ones in the Point2d module.

scaleAbout : Point2d units coordinates -> Basics.Float -> Polygon2d units coordinates -> Polygon2d units coordinates

Scale a polygon about a given center point by a given scale. If the given scale is negative, the order of the polygon's vertices will be reversed so that the resulting polygon still has its outer vertices in counterclockwise order and its inner vertices in clockwise order.

rotateAround : Point2d units coordinates -> Angle -> Polygon2d units coordinates -> Polygon2d units coordinates

Rotate a polygon around the given center point counterclockwise by the given angle.

translateBy : Vector2d units coordinates -> Polygon2d units coordinates -> Polygon2d units coordinates

Translate a polygon by the given displacement.

translateIn : Direction2d coordinates -> Quantity Basics.Float units -> Polygon2d units coordinates -> Polygon2d units coordinates

Translate a polygon in a given direction by a given distance.

mirrorAcross : Axis2d units coordinates -> Polygon2d units coordinates -> Polygon2d units coordinates

Mirror a polygon across the given axis. The order of the polygon's vertices will be reversed so that the resulting polygon still has its outer vertices in counterclockwise order and its inner vertices in clockwise order.

Unit conversions

at : Quantity Basics.Float (Quantity.Rate units2 units1) -> Polygon2d units1 coordinates -> Polygon2d units2 coordinates

Convert a polygon from one units type to another, by providing a conversion factor given as a rate of change of destination units with respect to source units.

at_ : Quantity Basics.Float (Quantity.Rate units1 units2) -> Polygon2d units1 coordinates -> Polygon2d units2 coordinates

Convert a polygon from one units type to another, by providing an 'inverse' conversion factor given as a rate of change of source units with respect to destination units.

Coordinate conversions

relativeTo : Frame2d units globalCoordinates { defines : localCoordinates } -> Polygon2d units globalCoordinates -> Polygon2d units localCoordinates

Take a polygon defined in global coordinates, and return it expressed in local coordinates relative to a given reference frame. If the given frame is left-handed, the order of the polygon's vertices will be reversed so that the resulting polygon still has its outer vertices in counterclockwise order and its inner vertices in clockwise order.

placeIn : Frame2d units globalCoordinates { defines : localCoordinates } -> Polygon2d units localCoordinates -> Polygon2d units globalCoordinates

Take a polygon considered to be defined in local coordinates relative to a given reference frame, and return that polygon expressed in global coordinates. If the given frame is left-handed, the order of the polygon's vertices will be reversed so that the resulting polygon still has its outer vertices in counterclockwise order and its inner vertices in clockwise order.

Triangulation

triangulate : Polygon2d units coordinates -> TriangularMesh (Point2d units coordinates)

Triangulate a polygon. This uses the TriangularMesh data types from ianmackenzie/elm-triangular-mesh. Triangulation is useful for things like WebGL rendering; you can define a polygon just by specifying its outline (and holes, if it has any)

Polygon with hole

then use this function to turn that polygon into a list of triangles which you can render using WebGL:

Polygon with hole

triangulateWith : TriangulationRule units coordinates -> Polygon2d units coordinates -> TriangularMesh (Point2d units coordinates)

Triangulate a polygon with additional control over the size of the triangles in the end result. For example, to triangulate a given polygon while making sure that every resulting triangle edge was no more than 10 centimeters long, you could use:

Polygon2d.triangulateWith
    (Polygon2d.maxEdgeLength (Length.centimeters 10))
    polygon

Note that this means that existing polygon edges may be split into smaller ones, and new vertices will likely end up being added inside the polygon. Also note that the resulting triangles may still be very thin; no particular attempt is made to avoid large or small angles in triangles.


type TriangulationRule units coordinates

A TriangulationRule controls the polygon triangulation process and determines how large the faces/edges are in the resulting triangular mesh.

maxEdgeLength : Quantity Basics.Float units -> TriangulationRule units coordinates

Ensure that every edge in a triangulation has at most the given length.

maxTriangleDimensions : Quantity Basics.Float units -> Quantity Basics.Float units -> TriangulationRule units coordinates

Ensure that every triangle in a triangulation has at most the given width and the given height.