poly2tri
Version:
A 2D constrained Delaunay triangulation library
480 lines (422 loc) • 15.6 kB
TypeScript
// Bundled type definitions for poly2tri.js
// Project: http://github.com/r3mi/poly2tri.js/
// Definitions by: Elemar Junior <https://github.com/elemarjr/>
// Updated by: Rémi Turboult <https://github.com/r3mi>
// TypeScript Version: 2.0
/*
* Poly2Tri Copyright (c) 2009-2014, Poly2Tri Contributors
* http://code.google.com/p/poly2tri/
*
* poly2tri.js (JavaScript port) (c) 2009-2017, Poly2Tri Contributors
* https://github.com/r3mi/poly2tri.js
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Poly2Tri nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* If you are not using a module system (e.g. CommonJS, RequireJS), you can access this library
* as a global variable `poly2tri` i.e. `window.poly2tri` in a browser.
*/
export as namespace poly2tri;
/**
* poly2tri.js supports using custom point class instead of {@linkcode Point}.
* Any "Point like" object with `{x, y}` attributes is supported
* to initialize the SweepContext polylines and points
* ([duck typing]{@link http://en.wikipedia.org/wiki/Duck_typing}).
*
* poly2tri.js might add extra fields to the point objects when computing the
* triangulation : they are prefixed with `_p2t_` to avoid collisions
* with fields in the custom class.
*
* @example
* const contour = [{x:100, y:100}, {x:100, y:300}, {x:300, y:300}, {x:300, y:100}];
* const swctx = new poly2tri.SweepContext(contour);
*/
export interface IPointLike {
/** x coordinate */
x: number;
/** y coordinate */
y: number;
}
// Alias
export type XY = IPointLike;
/**
* poly2tri library version
*/
export const VERSION: string;
/**
* A point {x, y}
*/
export class Point implements XY {
/** x coordinate */
public x: number;
/** y coordinate */
public y: number;
/**
* Construct a point
* @example
* const point = new poly2tri.Point(150, 150);
* @param x coordinate (0 if undefined)
* @param y coordinate (0 if undefined)
*/
constructor(x?: number, y?: number);
/**
* For pretty printing
* @example
* "p=" + new poly2tri.Point(5,42)
* // → "p=(5;42)"
* @returns `"(x;y)"`
*/
public toString(): string;
/**
* JSON output, only coordinates
* @example
* JSON.stringify(new poly2tri.Point(1,2))
* // → '{"x":1,"y":2}'
*/
public toJSON(): any;
/**
* Creates a copy of this Point object.
* @return new cloned point
*/
public clone(): Point;
/**
* Set this Point instance to the origin `(0; 0)`
* @return this (for chaining)
*/
public set_zero(): Point;
/**
* Set the coordinates of this instance.
* @param {number} x coordinate
* @param {number} y coordinate
* @return this (for chaining)
*/
public set(x: number, y: number): Point;
/**
* Negate this Point instance. (component-wise)
* @return this (for chaining)
*/
public negate(): Point;
/**
* Add another Point object to this instance. (component-wise)
* @param n - Point object.
* @return this (for chaining)
*/
public add(n: XY): Point;
/**
* Subtract this Point instance with another point given. (component-wise)
* @param n - Point object.
* @return this (for chaining)
*/
public sub(n: XY): Point;
/**
* Multiply this Point instance by a scalar. (component-wise)
* @param s scalar.
* @return this (for chaining)
*/
public mul(s: number): Point;
/**
* Return the distance of this Point instance from the origin.
* @return distance
*/
public length(): number;
/**
* Normalize this Point instance (as a vector).
* @return The original distance of this instance from the origo.
*/
public normalize(): number;
/**
* Test this Point object with another for equality.
* @param p - any "Point like" object with {x,y}
* @return `true` if same x and y coordinates, `false` otherwise.
*/
public equals(p: XY): boolean;
/**
* Negate a point component-wise and return the result as a new Point object.
* @param p - any "Point like" object with {x,y}
* @return the resulting Point object.
*/
public static negate(p: XY): Point;
/**
* Add two points component-wise and return the result as a new Point object.
* @param a - any "Point like" object with {x,y}
* @param b - any "Point like" object with {x,y}
* @return the resulting Point object.
*/
public static add(a: XY, b: XY): Point;
/**
* Subtract two points component-wise and return the result as a new Point object.
* @param a - any "Point like" object with {x,y}
* @param b - any "Point like" object with {x,y}
* @return the resulting Point object.
*/
public static sub(a: XY, b: XY): Point;
/**
* Multiply a point by a scalar and return the result as a new Point object.
* @param s - the scalar
* @param p - any "Point like" object with {x,y}
* @return the resulting Point object.
*/
public static mul(s: number, p: XY): Point;
/**
* Perform the cross product on either two points (result is a scalar)
* or a point and a scalar (result is a point).
* This function requires two parameters, either may be a Point object or a
* number.
* @param a - Point object or scalar.
* @param b - Point object or scalar.
* @return a Point object or a number, depending on the parameters.
*/
public static cross(a: XY, b: XY): number;
public static cross(a: XY, b: number): Point;
public static cross(a: number, b: XY): Point;
public static cross(a: number, b: number): number;
/**
* Point pretty printing. Delegates to the point's custom "toString()" method if exists,
* else simply prints x and y coordinates.
* @example
* xy.toString({x:5, y:42})
* // → "(5;42)"
* @example
* xy.toString({x:5,y:42,toString:function() {return this.x+":"+this.y;}})
* // → "5:42"
* @param p - point object with {x,y}
* @returns `"(x;y)"`
*/
public static toString(p: XY): string;
/**
* Compare two points component-wise. Ordered by y axis first, then x axis.
* @param a - point object with {x,y}
* @param b - point object with {x,y}
* @return `< 0` if `a < b` ; `> 0` if `a > b` ; `0` otherwise.
*/
public static compare(a: XY, b: XY): number;
/**
* Test two Point objects for equality.
* @param a - point object with {x,y}
* @param b - point object with {x,y}
* @return `true` if `a == b`, `false` otherwise.
*/
public static equals(a: XY, b: XY): boolean;
/**
* Peform the dot product on two vectors.
* @param a - any "Point like" object with {x,y}
* @param b - any "Point like" object with {x,y}
* @return the dot product
*/
public static dot(a: XY, b: XY): number;
}
/**
* Custom exception class to indicate invalid Point values
*/
export class PointError extends Error {
/**
* Invalid points
*/
public readonly points: ReadonlyArray<XY>;
/**
* Custom exception class to indicate invalid Point values
* @param message - error message
* @param points - invalid points
*/
constructor(message: string, points: Array<XY>);
}
/**
* Triangle defined by 3 points
*/
export class Triangle {
constructor(a: XY, b: XY, c: XY);
/**
* For pretty printing ex. `"[(5;42)(10;20)(21;30)]"`.
*/
public toString(): string;
/**
* Get one vertice of the triangle.
* The output triangles of a triangulation have vertices which are references
* to the initial input points (not copies): any custom fields in the
* initial points can be retrieved in the output triangles.
* @example
* const contour = [{x:100, y:100, id:1}, {x:100, y:300, id:2}, {x:300, y:300, id:3}];
* const swctx = new poly2tri.SweepContext(contour);
* swctx.triangulate();
* const triangles = swctx.getTriangles();
* typeof triangles[0].getPoint(0).id
* // → "number"
* @param index - vertice index: 0, 1 or 2
* @returns point
*/
public getPoint(index: 0 | 1 | 2): XY;
/**
* Get all 3 vertices of the triangle as an array
*/
public getPoints(): [XY, XY, XY];
public containsPoint(point: XY): boolean;
public containsPoints(p1: XY, p2: XY): boolean;
public isInterior(): boolean;
}
/**
* SweepContext constructor option
*/
export interface SweepContextOptions {
/**
* cloneArrays - if `true`, do a shallow copy of the Array parameters (contour, holes).
* Points inside arrays are never copied.
* Default is `false` : keep a reference to the array arguments, who will be modified in place.
*/
cloneArrays?: boolean;
}
/**
* Triangulation context
*/
export class SweepContext {
/**
* Constructor for the triangulation context.
* It accepts a simple polyline (with non repeating points),
* which defines the constrained edges.
*
* @example
* const contour = [
* new poly2tri.Point(100, 100),
* new poly2tri.Point(100, 300),
* new poly2tri.Point(300, 300),
* new poly2tri.Point(300, 100)
* ];
* const swctx = new poly2tri.SweepContext(contour, {cloneArrays: true});
* @example
* const contour = [{x:100, y:100}, {x:100, y:300}, {x:300, y:300}, {x:300, y:100}];
* const swctx = new poly2tri.SweepContext(contour, {cloneArrays: true});
*
* @param contour - array of point objects. The points can be either {@linkcode Point} instances,
* or any "Point like" custom class with `{x, y}` attributes.
* @param options - constructor options
*/
constructor(contour: Array<XY>, options?: SweepContextOptions);
/**
* Add a hole to the constraints
* @example
* const swctx = new poly2tri.SweepContext(contour);
* const hole = [
* new poly2tri.Point(200, 200),
* new poly2tri.Point(200, 250),
* new poly2tri.Point(250, 250)
* ];
* swctx.addHole(hole);
* @example
* const swctx = new poly2tri.SweepContext(contour);
* swctx.addHole([{x:200, y:200}, {x:200, y:250}, {x:250, y:250}]);
*
* @param polyline - array of "Point like" objects with {x,y}
*/
public addHole(polyline: Array<XY>): SweepContext;
/**
* Add several holes to the constraints.
* @example
* const swctx = new poly2tri.SweepContext(contour);
* const holes = [
* [ new poly2tri.Point(200, 200), new poly2tri.Point(200, 250), new poly2tri.Point(250, 250) ],
* [ new poly2tri.Point(300, 300), new poly2tri.Point(300, 350), new poly2tri.Point(350, 350) ]
* ];
* swctx.addHoles(holes);
* @example
* const swctx = new poly2tri.SweepContext(contour);
* const holes = [
* [{x:200, y:200}, {x:200, y:250}, {x:250, y:250}],
* [{x:300, y:300}, {x:300, y:350}, {x:350, y:350}]
* ];
* swctx.addHoles(holes);
*
* @param holes - array of array of "Point like" objects with {x,y}
*/
public addHoles(holes: Array<Array<XY>>): SweepContext;
/**
* Add a Steiner point to the constraints
* @example
* const swctx = new poly2tri.SweepContext(contour);
* const point = new poly2tri.Point(150, 150);
* swctx.addPoint(point);
* @example
* const swctx = new poly2tri.SweepContext(contour);
* swctx.addPoint({x:150, y:150});
*
* @param point - any "Point like" object with {x,y}
*/
public addPoint(point: XY): SweepContext;
/**
* Add several Steiner points to the constraints
* @example
* const swctx = new poly2tri.SweepContext(contour);
* const points = [
* new poly2tri.Point(150, 150),
* new poly2tri.Point(200, 250),
* new poly2tri.Point(250, 250)
* ];
* swctx.addPoints(points);
* @example
* const swctx = new poly2tri.SweepContext(contour);
* swctx.addPoints([{x:150, y:150}, {x:200, y:250}, {x:250, y:250}]);
*
* @param points - array of "Point like" object with {x,y}
*/
public addPoints(point: Array<XY>): SweepContext;
/**
* Triangulate the polygon with holes and Steiner points.
* Do this AFTER you've added the polyline, holes, and Steiner points
* @example
* const swctx = new poly2tri.SweepContext(contour);
* swctx.triangulate();
* const triangles = swctx.getTriangles();
*/
public triangulate(): SweepContext;
/**
* Get the bounding box of the provided constraints (contour, holes and
* Steinter points). Warning : these values are not available if the triangulation
* has not been done yet.
*
* @returns object with 'min' and 'max' Point
*/
public getBoundingBox(): { min: Point; max: Point; };
/**
* Get result of triangulation.
* The output triangles have vertices which are references
* to the initial input points (not copies): any custom fields in the
* initial points can be retrieved in the output triangles.
*
* @example
* const swctx = new poly2tri.SweepContext(contour);
* swctx.triangulate();
* const triangles = swctx.getTriangles();
* @example
* const contour = [{x:100, y:100, id:1}, {x:100, y:300, id:2}, {x:300, y:300, id:3}];
* const swctx = new poly2tri.SweepContext(contour);
* swctx.triangulate();
* const triangles = swctx.getTriangles();
* typeof triangles[0].getPoint(0).id
* // → "number"
*
* @returns array of triangles
*/
public getTriangles(): Array<Triangle>;
}