From 1f50b49eff08a114d4b5061d2a2d2529e84bcc83 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Tue, 25 Aug 2020 09:54:03 +0100 Subject: [PATCH] Earcut has now been exposed and is available via `Geom.Polygon.Earcut` and is fully documented. --- src/geom/polygon/Earcut.js | 59 ++++++++++++++++++++++++++++++++++++-- src/geom/polygon/index.js | 1 + 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/geom/polygon/Earcut.js b/src/geom/polygon/Earcut.js index 3e55e3a82..e469b4538 100644 --- a/src/geom/polygon/Earcut.js +++ b/src/geom/polygon/Earcut.js @@ -4,7 +4,60 @@ * @license {@link https://opensource.org/licenses/MIT|MIT License} */ -// Earcut 2.2.2 (January 21st 2020) +/** + * This module implements a modified ear slicing algorithm, optimized by z-order curve hashing and extended to + * handle holes, twisted polygons, degeneracies and self-intersections in a way that doesn't guarantee correctness + * of triangulation, but attempts to always produce acceptable results for practical data. + * + * Example: + * + * ```javascript + * const triangles = Phaser.Geom.Polygon.Earcut([10,0, 0,50, 60,60, 70,10]); // returns [1,0,3, 3,2,1] + * ``` + * + * Each group of three vertex indices in the resulting array forms a triangle. + * + * ```javascript + * // triangulating a polygon with a hole + * earcut([0,0, 100,0, 100,100, 0,100, 20,20, 80,20, 80,80, 20,80], [4]); + * // [3,0,4, 5,4,0, 3,4,7, 5,0,1, 2,3,7, 6,5,1, 2,7,6, 6,1,2] + * + * // triangulating a polygon with 3d coords + * earcut([10,0,1, 0,50,2, 60,60,3, 70,10,4], null, 3); + * // [1,0,3, 3,2,1] + * ``` + * + * If you pass a single vertex as a hole, Earcut treats it as a Steiner point. + * + * If your input is a multi-dimensional array (e.g. GeoJSON Polygon), you can convert it to the format + * expected by Earcut with `Phaser.Geom.Polygon.Earcut.flatten`: + * + * ```javascript + * var data = earcut.flatten(geojson.geometry.coordinates); + * var triangles = earcut(data.vertices, data.holes, data.dimensions); + * ``` + * + * After getting a triangulation, you can verify its correctness with `Phaser.Geom.Polygon.Earcut.deviation`: + * + * ```javascript + * var deviation = earcut.deviation(vertices, holes, dimensions, triangles); + * ``` + * Returns the relative difference between the total area of triangles and the area of the input polygon. + * 0 means the triangulation is fully correct. + * + * For more information see https://github.com/mapbox/earcut + * + * @function Phaser.Geom.Polygon.Earcut + * @since 3.50.0 + * + * @param {number[]} data - A flat array of vertex coordinate, like [x0,y0, x1,y1, x2,y2, ...] + * @param {number[]} [holeIndices] - An array of hole indices if any (e.g. [5, 8] for a 12-vertex input would mean one hole with vertices 5–7 and another with 8–11). + * @param {number} [dimensions=2] - The number of coordinates per vertex in the input array (2 by default). + * + * @return {number[]} An array of triangulated data. + */ + + // Earcut 2.2.2 (January 21st 2020) /* * ISC License @@ -26,8 +79,6 @@ 'use strict'; -module.exports = earcut; - function earcut(data, holeIndices, dim) { dim = dim || 2; @@ -702,3 +753,5 @@ earcut.flatten = function (data) { } return result; }; + +module.exports = earcut; diff --git a/src/geom/polygon/index.js b/src/geom/polygon/index.js index ee31ab284..9de3aa96a 100644 --- a/src/geom/polygon/index.js +++ b/src/geom/polygon/index.js @@ -9,6 +9,7 @@ var Polygon = require('./Polygon'); Polygon.Clone = require('./Clone'); Polygon.Contains = require('./Contains'); Polygon.ContainsPoint = require('./ContainsPoint'); +Polygon.Earcut = require('./Earcut'); Polygon.GetAABB = require('./GetAABB'); Polygon.GetNumberArray = require('./GetNumberArray'); Polygon.GetPoints = require('./GetPoints');