js-angusj-clipper
Version:
Polygon and line clipping and offsetting library for Javascript / Typescript - a port of Angus Johnson's clipper to WebAssembly / Asm.JS
242 lines (241 loc) • 15.3 kB
TypeScript
import { ClipType, PolyFillType, PolyType } from "./enums";
import { IntRect } from "./IntRect";
import { NativeClipperLibInstance } from "./native/NativeClipperLibInstance";
import { ReadonlyPath } from "./Path";
import { Paths, ReadonlyPaths } from "./Paths";
import { PolyTree } from "./PolyTree";
export interface ClipperInitOptions {
/**
* When this property is set to true, polygons returned in the solution parameter of the execute() method will have orientations opposite to their normal
* orientations.
*/
reverseSolution?: boolean;
/**
* When this property is set to true, polygons returned in the solution parameter of the execute() method will have orientations opposite to their normal
* orientations.
*/
strictlySimple?: boolean;
/**
* By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before
* clipping. When enabled the preserveCollinear property prevents this default behavior to allow these inner vertices to appear in the solution.
*/
preserveCollinear?: boolean;
}
export declare class Clipper {
private readonly _nativeLib;
private _clipper?;
/**
* By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before
* clipping. When enabled the preserveCollinear property prevents this default behavior to allow these inner vertices to appear in the solution.
*
* @return {boolean} - true if set, false otherwise
*/
get preserveCollinear(): boolean;
/**
* By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before
* clipping. When enabled the preserveCollinear property prevents this default behavior to allow these inner vertices to appear in the solution.
*
* @param value - value to set
*/
set preserveCollinear(value: boolean);
/**
* When this property is set to true, polygons returned in the solution parameter of the execute() method will have orientations opposite to their normal
* orientations.
*
* @return {boolean} - true if set, false otherwise
*/
get reverseSolution(): boolean;
/**
* When this property is set to true, polygons returned in the solution parameter of the execute() method will have orientations opposite to their normal
* orientations.
*
* @param value - value to set
*/
set reverseSolution(value: boolean);
/**
* Terminology:
* - A simple polygon is one that does not self-intersect.
* - A weakly simple polygon is a simple polygon that contains 'touching' vertices, or 'touching' edges.
* - A strictly simple polygon is a simple polygon that does not contain 'touching' vertices, or 'touching' edges.
*
* Vertices 'touch' if they share the same coordinates (and are not adjacent). An edge touches another if one of its end vertices touches another edge
* excluding its adjacent edges, or if they are co-linear and overlapping (including adjacent edges).
*
* Polygons returned by clipping operations (see Clipper.execute()) should always be simple polygons. When the StrictlySimply property is enabled,
* polygons returned will be strictly simple, otherwise they may be weakly simple. It's computationally expensive ensuring polygons are strictly simple
* and so this property is disabled by default.
*
* Note: There's currently no guarantee that polygons will be strictly simple since 'simplifying' is still a work in progress.
*
* @return {boolean} - true if set, false otherwise
*/
get strictlySimple(): boolean;
/**
* Terminology:
* - A simple polygon is one that does not self-intersect.
* - A weakly simple polygon is a simple polygon that contains 'touching' vertices, or 'touching' edges.
* - A strictly simple polygon is a simple polygon that does not contain 'touching' vertices, or 'touching' edges.
*
* Vertices 'touch' if they share the same coordinates (and are not adjacent). An edge touches another if one of its end vertices touches another edge
* excluding its adjacent edges, or if they are co-linear and overlapping (including adjacent edges).
*
* Polygons returned by clipping operations (see Clipper.execute()) should always be simple polygons. When the StrictlySimply property is enabled,
* polygons returned will be strictly simple, otherwise they may be weakly simple. It's computationally expensive ensuring polygons are strictly simple
* and so this property is disabled by default.
*
* Note: There's currently no guarantee that polygons will be strictly simple since 'simplifying' is still a work in progress.
*
* @param value - value to set
*/
set strictlySimple(value: boolean);
/**
* The Clipper constructor creates an instance of the Clipper class. One or more InitOptions may be passed as a parameter to set the corresponding properties.
* (These properties can still be set or reset after construction.)
*
* @param _nativeLib
* @param initOptions
*/
constructor(_nativeLib: NativeClipperLibInstance, initOptions?: ClipperInitOptions);
/**
* Any number of subject and clip paths can be added to a clipping task, either individually via the addPath() method, or as groups via the addPaths()
* method, or even using both methods.
*
* 'Subject' paths may be either open (lines) or closed (polygons) or even a mixture of both, but 'clipping' paths must always be closed. Clipper allows
* polygons to clip both lines and other polygons, but doesn't allow lines to clip either lines or polygons.
*
* With closed paths, orientation should conform with the filling rule that will be passed via Clipper's execute method.
*
* Path Coordinate range:
* Path coordinates must be between ± 9007199254740991, otherwise a range error will be thrown when attempting to add the path to the Clipper object.
* If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved by
* avoiding large integer math.
*
* Return Value:
* The function will return false if the path is invalid for clipping. A path is invalid for clipping when:
* - it has less than 2 vertices
* - it has 2 vertices but is not an open path
* - the vertices are all co-linear and it is not an open path
*
* @param path - Path to add
* @param polyType - Polygon type
* @param closed - If the path is closed
*/
addPath(path: ReadonlyPath, polyType: PolyType, closed: boolean): boolean;
/**
* Any number of subject and clip paths can be added to a clipping task, either individually via the addPath() method, or as groups via the addPaths()
* method, or even using both methods.
*
* 'Subject' paths may be either open (lines) or closed (polygons) or even a mixture of both, but 'clipping' paths must always be closed. Clipper allows
* polygons to clip both lines and other polygons, but doesn't allow lines to clip either lines or polygons.
*
* With closed paths, orientation should conform with the filling rule that will be passed via Clipper's execute method.
*
* Path Coordinate range:
* Path coordinates must be between ± 9007199254740991, otherwise a range error will be thrown when attempting to add the path to the Clipper object.
* If coordinates can be kept between ± 0x3FFFFFFF (± 1.0e+9), a modest increase in performance (approx. 15-20%) over the larger range can be achieved
* by avoiding large integer math.
*
* Return Value:
* The function will return false if the path is invalid for clipping. A path is invalid for clipping when:
* - it has less than 2 vertices
* - it has 2 vertices but is not an open path
* - the vertices are all co-linear and it is not an open path
*
* @param paths - Paths to add
* @param polyType - Paths polygon type
* @param closed - If all the inner paths are closed
*/
addPaths(paths: ReadonlyPaths, polyType: PolyType, closed: boolean): boolean;
/**
* The Clear method removes any existing subject and clip polygons allowing the Clipper object to be reused for clipping operations on different polygon sets.
*/
clear(): void;
/**
* This method returns the axis-aligned bounding rectangle of all polygons that have been added to the Clipper object.
*
* @return {{left: number, right: number, top: number, bottom: number}} - Bounds
*/
getBounds(): IntRect;
/**
* Once subject and clip paths have been assigned (via addPath and/or addPaths), execute can then perform the clipping operation (intersection, union,
* difference or XOR) specified by the clipType parameter.
*
* The solution parameter in this case is a Paths or PolyTree structure. The Paths structure is simpler than the PolyTree structure. Because of this it is
* quicker to populate and hence clipping performance is a little better (it's roughly 10% faster). However, the PolyTree data structure provides more
* information about the returned paths which may be important to users. Firstly, the PolyTree structure preserves nested parent-child polygon relationships
* (ie outer polygons owning/containing holes and holes owning/containing other outer polygons etc). Also, only the PolyTree structure can differentiate
* between open and closed paths since each PolyNode has an IsOpen property. (The Path structure has no member indicating whether it's open or closed.)
* For this reason, when open paths are passed to a Clipper object, the user must use a PolyTree object as the solution parameter, otherwise an exception
* will be raised.
*
* When a PolyTree object is used in a clipping operation on open paths, two ancilliary functions have been provided to quickly separate out open and
* closed paths from the solution - OpenPathsFromPolyTree and ClosedPathsFromPolyTree. PolyTreeToPaths is also available to convert path data to a Paths
* structure (irrespective of whether they're open or closed).
*
* There are several things to note about the solution paths returned:
* - they aren't in any specific order
* - they should never overlap or be self-intersecting (but see notes on rounding)
* - holes will be oriented opposite outer polygons
* - the solution fill type can be considered either EvenOdd or NonZero since it will comply with either filling rule
* - polygons may rarely share a common edge (though this is now very rare as of version 6)
*
* The subjFillType and clipFillType parameters define the polygon fill rule to be applied to the polygons (ie closed paths) in the subject and clip
* paths respectively. (It's usual though obviously not essential that both sets of polygons use the same fill rule.)
*
* execute can be called multiple times without reassigning subject and clip polygons (ie when different clipping operations are required on the
* same polygon sets).
*
* @param clipType - Clip operation type
* @param subjFillType - Fill type of the subject polygons
* @param clipFillType - Fill type of the clip polygons
* @param cleanDistance - Clean distance over the output, or undefined for no cleaning.
* @return {Paths | undefined} - The solution or undefined if there was an error
*/
executeToPaths(clipType: ClipType, subjFillType: PolyFillType, clipFillType: PolyFillType, cleanDistance: number | undefined): Paths | undefined;
/**
* Once subject and clip paths have been assigned (via addPath and/or addPaths), execute can then perform the clipping operation (intersection, union,
* difference or XOR) specified by the clipType parameter.
*
* The solution parameter can be either a Paths or PolyTree structure. The Paths structure is simpler than the PolyTree structure. Because of this it is
* quicker to populate and hence clipping performance is a little better (it's roughly 10% faster). However, the PolyTree data structure provides more
* information about the returned paths which may be important to users. Firstly, the PolyTree structure preserves nested parent-child polygon relationships
* (ie outer polygons owning/containing holes and holes owning/containing other outer polygons etc). Also, only the PolyTree structure can differentiate
* between open and closed paths since each PolyNode has an IsOpen property. (The Path structure has no member indicating whether it's open or closed.)
* For this reason, when open paths are passed to a Clipper object, the user must use a PolyTree object as the solution parameter, otherwise an exception
* will be raised.
*
* When a PolyTree object is used in a clipping operation on open paths, two ancilliary functions have been provided to quickly separate out open and
* closed paths from the solution - OpenPathsFromPolyTree and ClosedPathsFromPolyTree. PolyTreeToPaths is also available to convert path data to a Paths
* structure (irrespective of whether they're open or closed).
*
* There are several things to note about the solution paths returned:
* - they aren't in any specific order
* - they should never overlap or be self-intersecting (but see notes on rounding)
* - holes will be oriented opposite outer polygons
* - the solution fill type can be considered either EvenOdd or NonZero since it will comply with either filling rule
* - polygons may rarely share a common edge (though this is now very rare as of version 6)
*
* The subjFillType and clipFillType parameters define the polygon fill rule to be applied to the polygons (ie closed paths) in the subject and clip
* paths respectively. (It's usual though obviously not essential that both sets of polygons use the same fill rule.)
*
* execute can be called multiple times without reassigning subject and clip polygons (ie when different clipping operations are required on the
* same polygon sets).
*
* @param clipType - Clip operation type
* @param subjFillType - Fill type of the subject polygons
* @param clipFillType - Fill type of the clip polygons
* @return {PolyTree | undefined} - The solution or undefined if there was an error
*/
executeToPolyTee(clipType: ClipType, subjFillType: PolyFillType, clipFillType: PolyFillType): PolyTree | undefined;
/**
* Checks if the object has been disposed.
*
* @return {boolean} - true if disposed, false if not
*/
isDisposed(): boolean;
/**
* Since this library uses WASM/ASM.JS internally for speed this means that you must dispose objects after you are done using them or mem leaks will occur.
* (If the runtime supports FinalizationRegistry then this becomes non-mandatory, but still recommended).
*/
dispose(): void;
}