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
Geometry.Types.Polygon2d
singleLoop : List Point2d -> Polygon2d
Construct a polygon without holes from a list of its vertices:
rectangle =
Polygon2d.singleLoop
[ Point2d.fromCoordinates ( 1, 1 )
, Point2d.fromCoordinates ( 3, 1 )
, Point2d.fromCoordinates ( 3, 2 )
, Point2d.fromCoordinates ( 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.
with : { outerLoop : List Point2d, innerLoops : List (List Point2d) } -> Polygon2d
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.fromCoordinates ( 0, 0 )
, Point2d.fromCoordinates ( 3, 0 )
, Point2d.fromCoordinates ( 3, 3 )
, Point2d.fromCoordinates ( 0, 3 )
]
innerLoop =
[ Point2d.fromCoordinates ( 1, 1 )
, Point2d.fromCoordinates ( 1, 2 )
, Point2d.fromCoordinates ( 2, 2 )
, Point2d.fromCoordinates ( 2, 1 )
]
squareWithHole =
Polygon2d.with
{ outerLoop = outerLoop
, innerLoops = [ innerLoop ]
}
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 -> Polygon2d
Build the convex hull of a list of points:
This is an O(n log n) operation.
outerLoop : Polygon2d -> List Point2d
Get the list of vertices definining the outer loop (border) of a polygon. The vertices will be in counterclockwise order.
Polygon2d.outerLoop squareWithHole
--> [ Point2d.fromCoordinates ( 0, 0 )
--> , Point2d.fromCoordinates ( 3, 0 )
--> , Point2d.fromCoordinates ( 3, 3 )
--> , Point2d.fromCoordinates ( 0, 3 )
--> ]
innerLoops : Polygon2d -> List (List Point2d)
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.fromCoordinates ( 1, 1 )
--> , Point2d.fromCoordinates ( 1, 2 )
--> , Point2d.fromCoordinates ( 2, 2 )
--> , Point2d.fromCoordinates ( 2, 1 )
--> ]
--> ]
vertices : Polygon2d -> List Point2d
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.
Polygon2d.vertices squareWithHole
--> [ Point2d ( 0, 0 )
--> , Point2d ( 3, 0 )
--> , Point2d ( 3, 3 )
--> , Point2d ( 0, 3 )
--> , Point2d ( 1, 1 )
--> , Point2d ( 1, 2 )
--> , Point2d ( 2, 2 )
--> , Point2d ( 2, 1 )
--> ]
edges : Polygon2d -> List LineSegment2d
Get all edges of a polygon. This will include both outer edges and inner (hole) edges.
Polygon2d.edges squareWithHole
--> [ LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 0, 0 )
--> , Point2d.fromCoordinates ( 3, 0 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 3, 0 )
--> , Point2d.fromCoordinates ( 3, 3 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 3, 3 )
--> , Point2d.fromCoordinates ( 0, 3 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 0, 3 )
--> , Point2d.fromCoordinates ( 0, 0 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 1, 1 )
--> , Point2d.fromCoordinates ( 1, 2 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 1, 2 )
--> , Point2d.fromCoordinates ( 2, 2 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 2, 2 )
--> , Point2d.fromCoordinates ( 2, 1 )
--> )
--> , LineSegment2d.fromEndpoints
--> ( Point2d.fromCoordinates ( 2, 1 )
--> , Point2d.fromCoordinates ( 1, 1 )
--> )
--> ]
perimeter : Polygon2d -> Basics.Float
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
--> 16
area : Polygon2d -> Basics.Float
Get the area of a polygon. This value will never be negative.
Polygon2d.area squareWithHole
--> 8
boundingBox : Polygon2d -> Maybe BoundingBox2d
Get the minimal bounding box containing a given polygon. Returns Nothing
if the polygon has no vertices.
Polygon2d.boundingBox rectangle
--> Just
--> (BoundingBox2d.fromExtrema
--> { minX = 1
--> , maxX = 3
--> , minY = 1
--> , maxY = 2
--> }
--> )
Transforming a polygon is equivalent to transforming each of its vertices.
scaleAbout : Point2d -> Basics.Float -> Polygon2d -> Polygon2d
Scale a polygon about a given center point by a given scale.
point =
Point2d.fromCoordinates ( 2, 1 )
Polygon2d.scaleAbout point 2 rectangle
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( 0, 1 )
--> , Point2d.fromCoordinates ( 4, 1 )
--> , Point2d.fromCoordinates ( 4, 3 )
--> , Point2d.fromCoordinates ( 0, 3 )
--> ]
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 -> Basics.Float -> Polygon2d -> Polygon2d
Rotate a polygon around the given center point counterclockwise by the given angle (in radians).
rectangle
|> Polygon2d.rotateAround Point2d.origin
(degrees 90)
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( -1, 1 )
--> , Point2d.fromCoordinates ( -1, 3 )
--> , Point2d.fromCoordinates ( -2, 3 )
--> , Point2d.fromCoordinates ( -2, 1 )
--> ]
translateBy : Vector2d -> Polygon2d -> Polygon2d
Translate a polygon by the given displacement.
displacement =
Vector2d.fromComponents ( 2, 3 )
Polygon2d.translateBy displacement rectangle
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( 3, 4 )
--> , Point2d.fromCoordinates ( 5, 4 )
--> , Point2d.fromCoordinates ( 5, 5 )
--> , Point2d.fromCoordinates ( 3, 5 )
--> ]
translateIn : Direction2d -> Basics.Float -> Polygon2d -> Polygon2d
Translate a polygon in a given direction by a given distance;
Polygon2d.translateIn direction distance
is equivalent to
Polygon2d.translateBy
(Vector2d.withLength distance direction)
mirrorAcross : Axis2d -> Polygon2d -> Polygon2d
Mirror a polygon across the given axis.
Polygon2d.mirrorAcross Axis2d.x rectangle
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( 1, -1 )
--> , Point2d.fromCoordinates ( 3, -1 )
--> , Point2d.fromCoordinates ( 3, -2 )
--> , Point2d.fromCoordinates ( 1, -2 )
--> ]
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.
relativeTo : Frame2d -> Polygon2d -> Polygon2d
Take a polygon defined in global coordinates, and return it expressed in local coordinates relative to a given reference frame.
localFrame =
Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
Polygon2d.relativeTo localFrame rectangle
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( 0, -1 )
--> , Point2d.fromCoordinates ( 2, -1 )
--> , Point2d.fromCoordinates ( 2, 0 )
--> , Point2d.fromCoordinates ( 0, 0 )
--> ]
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 -> Polygon2d -> Polygon2d
Take a polygon considered to be defined in local coordinates relative to a given reference frame, and return that polygon expressed in global coordinates.
localFrame =
Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))
Polygon2d.placeIn localFrame rectangle
--> Polygon2d.singleLoop
--> [ Point2d.fromCoordinates ( 2, 3 )
--> , Point2d.fromCoordinates ( 4, 3 )
--> , Point2d.fromCoordinates ( 4, 4 )
--> , Point2d.fromCoordinates ( 2, 4 )
--> ]
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.
triangulate : Polygon2d -> TriangularMesh Point2d
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)
then use this function to turn that polygon into a list of triangles which you can render using WebGL: