Documentation
    Preparing search index...

    Function triangulatePolygon

    • Triangulates a simple polygon, with optional holes, into an indexed triangle set (§52 "concave polygons", "holes", "index-buffer reuse").

      const indices = triangulatePolygon([
      { x: 0, y: 0 }, { x: 2, y: 0 }, { x: 2, y: 1 },
      { x: 1, y: 1 }, { x: 1, y: 2 }, { x: 0, y: 2 },
      ]);
      indices.length / 3; // 4 triangles for this L

      The concatenation of the rings, in the order they were passed: the outline occupies 0 … outline.length - 1, the first hole the block after it, and so on. A caller that lays its vertices out the same way — and both builders in this package do — can upload the returned array unchanged. No vertices are created, moved, or merged, which is what makes one triangulation reusable for two caps of an extrusion.

      The array is the narrowest type that can address those vertices (Uint16Array up to 65 536 points), matching every other builder here.

      Either input winding is accepted, for the outline and for each hole independently — the tessellator reads each ring's signed area and walks it in whichever direction it needs. Every emitted triangle is counter-clockwise seen from +Z (§7a), so a caller placing the points in the XY plane gets front faces without inspecting its own input.

      A vertex lying exactly on the segment between its two neighbours is dropped before clipping: it adds nothing to the region and would only produce a zero-area triangle. Such a vertex therefore appears in no triangle, and indices.length / 3 is effective vertices + 2 × holes − 2, not points − 2. The vertex itself is untouched in the caller's array — this function never rewrites input (§85).

      Every one of these throws RangeError rather than producing triangles that do not describe the requested region:

      • a ring of fewer than 3 points, or any non-finite coordinate;
      • a ring that repeats a point consecutively (a zero-length edge), or doubles straight back on itself (a spike);
      • a ring enclosing zero area — including the symmetric figure-of-eight whose lobes cancel;
      • any self-intersection or touching: two edges that cross, two rings that touch, a vertex sitting on a foreign edge (§52's "self-intersections where well-defined" is staged; see this module's header);
      • a hole that is not inside the outline, or that is inside another hole (islands are not a §52 requirement and would need a nesting-parity pass);
      • a configuration of two or more holes whose bridges leave the ear clipper no corner to cut — measured at roughly two per thousand adversarial cases, never wrong when it succeeds; see this module's header.

      Parameters

      • outline: readonly Point2D[]

        The closed outer ring. The last point is not repeated; the ring closes from the last point back to the first.

      • holes: readonly (readonly Point2D[])[] = []

        Closed inner rings, each in either winding, each strictly inside outline and disjoint from the others.

      Returns GeometryIndexArray