This page is in progress.
The Javascript Clipper Library performs clipping and offsetting of both lines and polygons.
A number of features set Clipper apart from other clipping libraries:
Current Javascript Clipper version: 6.1.0.1 (C# 6.1.0)
Original C# version's Author & copyright:
Angus Johnson. Copyright © 2010-2013
License, terms and conditions: Boost Software License
Javascript Clipper's Author & copyright:
Timo. Copyright © 2012-2013
License, terms and conditions: Boost Software License
Javascript Clipper uses implementation of Tom Wu's JSBN library, which has BSD license.
Distribution package contents:
The ZIP package contains the Clipper library's source code as minified and unminified and a number of demo applications. The library was initially written in Delphi Pascal, but was then made available also in C++, C# and Python. The library's source code in each language is about 5000 lines. Javascript implementation is longer, about 7000 lines due to JSBN library and some helper functions. The included sample applications show how Clipper can be used with SVG and Canvas.
Download Link:
References:
Read about references regarding clipping and offsetting algorithms.
See also:
OffsetPaths, ClipType, Path, PolyFillType
Boolean use_int32 Boolean use_xyz Boolean use_lines Boolean use_deprecated
use_int32:
Not implemented in Javascript.
use_xyz:
Adds a 'Z' member to IntPoint with only a minor cost to perfomance. For more details see Clipper's Clipper.ZFillFunction property. (Disabled by default)
use_lines:
Enables open path (line) clipping. If line clipping is disabled, there's generally a very small (ie ~5%) improvement in performance. (Enabled by default)
use_deprecated:
Enables code developed with versions of Clipper prior to version 6 to compile without changes. This exposes compatibility code that will be removed in a future update. (Enabled by default)
Usage:
var use_xyz = true; var use_lines = true; var use_deprecated = true;
See also:
Clipper.ZFillFunction, IntPoint
Boolean AddPath(Path pg, PolyType polyType, Boolean closed);
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 ± 4503599627370495 (sqrt(2^106 -1)/2), otherwise a range error will be thrown when attempting to add the path to the Clipper object. If coordinates can be kept between ± 47453132 (sqrt(2^53 -1)/2), an increase in performance (approx. 40-50%) over the larger range can be achieved by avoiding large integer math.
Return Value:
The function will return false if the path is empty or almost empty. A path is almost empty when:
Usage:
var cpr = new ClipperLib.Clipper(); var path = [{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]; cpr.AddPath(path, ClipperLib.PolyType.ptSubject, true);
See also:
Example, Clipper.Execute, AddPaths, Orientation, Defines, Path, PolyFillType, PolyType
Boolean AddPaths(Paths ppg, PolyType polyType, Boolean closed);
Same functionality as in AddPath(), but the parameter is Paths.
Usage:
var cpr = new ClipperLib.Clipper(); var paths = [[{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}], [{X:20,Y:20},{X:20,Y:100},{X:100,Y:100},{X:100,Y:20}]];; cpr.AddPaths(paths, ClipperLib.PolyType.ptSubject, true);
See also:
Example, Clipper.Execute, AddPath, Orientation, Defines, Paths, PolyFillType, PolyType
void Clear();
The Clear method removes any existing subject and clip polygons allowing the Clipper object to be reused for clipping operations on different polygon sets.
Usage:
cpr.Clear();
IntRect GetBounds();
This method returns the axis-aligned bounding rectangle of all polygons that have been added to the Clipper object.
Usage:
var cpr = new ClipperLib.Clipper(); var path = [{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]; cpr.AddPath(path, ClipperLib.PolyType.ptSubject, true); var bounds = cpr.GetBounds(); // bounds is now: {"left":10,"top":10,"right":110,"bottom":110}
Clipper Clipper(InitOptions initOptions = 0);
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.)
Usage:
var cpr = new ClipperLib.Clipper(); // or var cpr = new ClipperLib.Clipper(ClipperLib.Clipper.ioStrictlySimple | ClipperLib.Clipper.ioPreserveCollinear); // or var cpr = new ClipperLib.Clipper(2 | 4);
See also:
PreserveCollinear, ReverseSolution, StrictlySimple, InitOptions
Boolean Execute(ClipType clipType, Paths solution, PolyFillType subjFillType, PolyFillType clipFillType); Boolean Execute(ClipType clipType, PolyTree solution, PolyFillType subjFillType, PolyFillType clipFillType);
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 and faster (roughly 10%) than the PolyTree stucture. PolyTree holds information of parent-child relationchips of paths and also whether they are open or closed.
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).
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).
Usage:
function DrawPolygons(paths, color) {/* ... */} function Main(args) { var subj = [[{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}], [{X:20,Y:20},{X:20,Y:100},{X:100,Y:100},{X:100,Y:20}]]; var clip = [[{X:50,Y:50},{X:150,Y:50},{X:150,Y:150},{X:50,Y:150}], [{X:60,Y:60},{X:60,Y:140},{X:140,Y:140},{X:140,Y:60}]]; DrawPolygons(subj, 0x8033FFFF); DrawPolygons(clip, 0x80FFFF33); var solution = new ClipperLib.Paths(); var c = new ClipperLib.Clipper(); c.AddPaths(subj, ClipperLib.PolyType.ptSubject, true); c.AddPaths(clips, ClipperLib.PolyType.ptClip, true); c.Execute(ClipperLib.ClipType.ctIntersection, solution); DrawPolygons(solution, 0x40808080); } Main();
See also:
Rounding, ClipperBase.AddPath, ClipperBase.AddPaths, PolyNode.IsOpen, PolyTree, ClosedPathsFromPolyTree, OpenPathsFromPolyTree, PolyTreeToPaths, ClipType, Path, Paths, PolyFillType
Number Area(Path poly)
This function returns the area of the supplied polygon. (It's assumed that the path will be closed.) Depending on orientation, this value may be positive or negative. If Orientation is true, then the area will be positive and conversely, if Orientation is false, then the area will be negative.
Usage:
var area = ClipperLib.Clipper.Area(polygon);
** See also:**
Orientation, Path
Boolean Orientation(Path poly)
Returns true, if polygon area is >=0.
Orientation is only important to closed paths. Given that vertices are declared in a specific order, orientation refers to the direction (clockwise or counter-clockwise) that these vertices progress around a closed path.
Orientation is also dependent on axis direction:
On Y-axis positive upward displays, Orientation will return true if the polygon's orientation is counter-clockwise.
On Y-axis positive downward displays, Orientation will return true if the polygon's orientation is clockwise.
See more in the original documentation.
Usage:
var orientation = ClipperLib.Clipper.Orientation(polygon);
See also:
Area, Clipper.ReverseSolution, Path
Path CleanPolygon(Path path, Number distance)
This function is needed to prevent distortion that is caused by too near vertices and/or micro-self-interserctions.
Removes vertices:
that join co-linear edges, or join edges that are almost co-linear (such that if the vertex was moved no more than the specified distance the edges would be co-linear)
that are within the specified distance of an adjacent vertex
that are within the specified distance of a semi-adjacent vertex together with their out-lying vertices
Vertices are semi-adjacent when they are separated by a single (out-lying) vertex.
The distance parameter's default value is approximately √2 so that a vertex will be removed when adjacent or semi-adjacent vertices having their corresponding X and Y coordinates differing by no more than 1 unit. (If the egdes are semi-adjacent the out-lying vertex will be removed too.)
According to tests, the most proper distance value to remove artifacts before offsetting is 0.1 * scale
Usage:
var path = [{"X":10,"Y":10},{"X":11,"Y":11},{"X":110,"Y":10},{"X":110,"Y":110}, {"X":10,"Y":110}]; var cleaned_path = ClipperLib.Clipper.CleanPolygon(path, 1.1); // point {"X":11,"Y":11} is now removed
See also:
CleanPolygons, SimplifyPolygon, Path
Paths CleanPolygons(Paths polys, Number distance)
Same functionality as in ClipperLib.CleanPolygon, but the parameter is of type Paths.
According to tests, the most proper distance value to remove artifacts before offsetting is 0.1 * scale
Usage:
var paths = [[{X:10,Y:10},{X:11,Y:11},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}], [{X:20,Y:20},{X:20,Y:100},{X:100,Y:100},{X:100,Y:20}]]; var cleaned_paths = ClipperLib.Clipper.CleanPolygons(paths, 1.1); // point {"X":11,"Y":11} is removed
See also:
CleanPolygon, SimplifyPolygons
Paths MinkowskiSum(Path shape, Path path, Boolean isClosed)
Minkowski Addition is performed by adding each point in a polygon 'shape' to the set of points in an open or closed path. The resulting polygon (or polygons) defines the region that the polygon 'shape' would pass over in moving from the beginning to the end of the 'path'.
// Star shape ... var path = [{"X":89.85,"Y":355.85},{"X":131.72,"Y":227.13},{"X":22.1,"Y":147.57},{"X":157.6,"Y":147.57},{"X":199.47,"Y":18.85},{"X":241.34,"Y":147.57},{"X":376.84,"Y":147.57},{"X":267.22,"Y":227.13},{"X":309.09,"Y":355.85},{"X":199.47,"Y":276.29}]; // Diagonal brush shape ... var shape = [{"X":4,"Y":-6},{"X":6,"Y":-6},{"X":-4,"Y":6},{"X":-6,"Y":6}]; var solution = ClipperLib.Clipper.MinkowskiSum(shape, path, true);
See also:
MinkowskiDiff, Path, Paths
Paths MinkowskiDiff(Path poly, Path path, Boolean isClosed)
Minkowski Difference is performed by subtracting each point in a polygon from the set of points in an open or closed path. A key feature of Minkowski Difference is that when it's applied to two polygons, the resulting polygon will contain the coordinate space origin when the original polygons overlap (ie when they collide).
See also:
MinkowskiSum, Path, Paths
Paths OpenPathsFromPolyTree(PolyTree polytree)
This function filters out closed paths from the PolyTree structure and returns only open paths in a Paths structure.
Usage:
// ... polytree is populated automatically by Execute() var lines = ClipperLib.Clipper.OpenPathsFromPolyTree(polytree);
Paths ClosedPathsFromPolyTree(PolyTree polytree)
This function filters out open paths from the PolyTree structure and returns only closed paths in a Paths structure.
Usage:
// ... polytree is populated automatically by Execute() var polygons = ClipperLib.Clipper.ClosedPathsFromPolyTree(polytree);
Paths OffsetPaths(Paths polys, Number delta, JoinType jointype = JoinType.jtSquare, EndType endtype = EndType.etClosed, Number limit)
Deprecated. (See ClipperLib.ClipperOffset.)
This function offsets the 'polys' parameter by the 'delta' amount. 'polys' may be open or closed paths. With closed paths (polygons), positive delta values 'expand' outer contours and 'shrink' inner 'hole' contours. Negative deltas do the reverse. With open paths (lines), the sign of the delta value is ignored since it's not possible to 'shrink' open paths.
Edge joins may be one of three jointypes - jtMiter, jtSquare or jtRound. (See the image below for examples.)
The meaning and use of the limit parameter depends on jointype:
jtMiter: limit sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. The default value is 2 (ie twice delta) which is also the smallest allowed value. If the angle is acute enough to require squaring, then squaring will occur at 1 times delta. If offsetting was allowed without any limits (ie without squaring), then offsetting at very acute angles would produce unacceptably long 'spikes'.
jtRound: limit sets the maximum distance that rounded joins can deviate from their true arcs (since it would require an infinite number of vertices to perfectly represent an arc). The default limit is 0.25 units though realistically precision can never be better than 0.5 since arc coordinates will still be rounded to integer values. When offsetting polygons with very large coordinate values (typically as a result of scaling), it's advisable to increase limit to maintain consistent precisions at all joins because the maximum number of vertices allowed in any arc is 222. (This hard coded upper limit has been chosen because the imprecision in a circle constructed with 222 vertices will be only 1/10000th its radius and, not only is creating very large numbers of arc vertices computationally expensive, it can cause out-of-memory problems.)
jtSquare: The limit parameter is ignored since squaring will be applied uniformally at 1 times delta.
Self-intersections in closed paths must be removed before the paths are passed to OffsetPaths.
Usage:
var paths = [[{"X":224,"Y":146},{"X":224,"Y":213},{"X":201,"Y":191},{"X":179,"Y":235},{"X":134,"Y":191},{"X":179,"Y":168},{"X":157,"Y":146}]]; var offset_paths = ClipperLib.Clipper.OffsetPaths(paths, 10, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etRound, 0.25);
See also:
ClipperOffset, ClipperOffset.JoinType, Path
Paths PolyTreeToPaths(PolyTree polytree)
This function converts a PolyTree structure into a Paths structure (whether they are open or closed). To differentiate open and closed paths, use OpenPathsFromPolyTree() or ClosedPathsFromPolyTree().
Usage:
// ... polytree is populated automatically by Execute() var paths = ClipperLib.Clipper.PolyTreeToPaths(polytree);
Paths SimplifyPolygon(Path poly, PolyFillType fillType = PolyFillType.pftEvenOdd)
Removes self-intersections from the supplied polygon (by performing a boolean union operation using the nominated PolyFillType).
Polygons with non-contiguous duplicate vertices (ie 'touching') will be split into two polygons.
// five-pointed star with self-intersections... var five_pointed_star = [{"X":147,"Y":313},{"X":247,"Y":34},{"X":338,"Y":312},{"X":86,"Y":123},{"X":404,"Y":124}]; var ten_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftNonZero); // ten_pointed_star is a ten-pointed star with no self-intersections var fifteen_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftEvenOdd); // fifteen_pointed_star is a fifteen-pointed star with no self-intersections
See also:
Clipper.StrictlySimple, CleanPolygon, Path, PolyFillType
Paths SimplifyPolygons(Paths polys, PolyFillType fillType = PolyFillType.pftEvenOdd)
The same functionality as in ClipperLib.Clipper.SimplifyPolygon(), but the parameter is of type Paths.
// five-pointed star with self-intersections... var five_pointed_star = [[{"X":147,"Y":313},{"X":247,"Y":34},{"X":338,"Y":312},{"X":86,"Y":123},{"X":404,"Y":124}]]; var ten_pointed_star = ClipperLib.Clipper.SimplifyPolygons(five_pointed_star, ClipperLib.PolyFillType.pftNonZero); // ten_pointed_star is a ten-pointed star with no self-intersections var fifteen_pointed_star = ClipperLib.Clipper.SimplifyPolygon(five_pointed_star, ClipperLib.PolyFillType.pftEvenOdd); // fifteen_pointed_star is a fifteen-pointed star with no self-intersections
See also:
Clipper.StrictlySimple, CleanPolygons, PolyFillType
// Call Path.reverse().
Reverses the vertex order (and hence orientation) in a path.
var path = [{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]; path.reverse(); // path is now [[{"X":10,"Y":110},{"X":110,"Y":110},{"X":110,"Y":10},{"X":10,"Y":10}]]
void ReversePaths(Paths p)
Reverses the vertex order (and hence orientation) in each contained path.
Usage:
var paths = [[{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]]; ClipperLib.Clipper.ReversePaths(paths); // paths is now [[{"X":10,"Y":110},{"X":110,"Y":110},{"X":110,"Y":10},{"X":10,"Y":10}]]
Boolean PreserveCollinear;
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.
Usage:
var cpr = new ClipperLib.Clipper(); cpr.PreserveCollinear = true;
See also:
ClipperLib.Clipper()
Boolean ReverseSolution;
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.
Usage:
var cpr = new ClipperLib.Clipper(); cpr.ReverseSolution = true;
See also:
Execute, Orientation
Boolean StrictlySimple;
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.
In the image above, the two examples show weakly simple polygons being broken into two strictly simple polygons. (The outlines with arrows are intended to aid visualizing vertex order.)
See also the article on Simple Polygon on Wikipedia.
Usage:
var cpr = new ClipperLib.Clipper(); cpr.StrictlySimple = true;
See also:
Execute, SimplifyPolygons
void ZFillCallback ZFillFunction;
This property is only exposed if the Preprocessor directive use_xyz has been defined. (If it is defined, a Z member will be added to the IntPoint structure.) When a custom callback function is assigned it will be called during clipping operations so custom Z values can be assigned intersection vertices.
Vertices in the solution of clipping operations more often than not correspond to input (subject or clip) vertices, but those vertices created at edge intersections do not. While the X and Y coordinates for these 'intersection' vertices are obviously defined by the points of intersection, there's no obvious way to assign their Z values. It really depends on the needs of the library user. While there are 4 vertices directly influencing an intersection vertex (ie the vertices on each end of the 2 intersecting edges), in an attempt to keep things simple only the vertices bounding one edge will be passed to the callback function.
The CurvesDemo application in the Curves directory in the distribution zip package shows how the Z member together with the callback function can be used to flatten curved paths (defined by control points) and after clipping, to 'de-flatten' or reconstruct curved paths in the clipping solution.
Usage:
var cpr = new ClipperLib.Clipper(); cpr.ZFillFunction = function (vert1, vert2, intersectPt) { /* function body */ }; // or var ClipCallback = function (vert1, vert2, intersectPt) { /* function body */ }; cpr.ZFillFunction = ClipCallback;
See also:
Defines, IntPoint, ZFillCallback
Number ClipType {ctIntersection: 0, ctUnion: 1, ctDifference: 2, ctXor: 3};
There are four boolean operations - AND, OR, NOT & XOR.
Given that subject and clip polygon brush 'filling' is defined both by their vertices and their respective filling rules, the four boolean operations can be applied to polygons to define new filling regions:
All polygon clipping is performed with a Clipper object with the specific boolean operation indicated by the ClipType parameter passed in its Execute method.
With regard to open paths (polylines), clipping rules generally match those of closed paths (polygons).
However, when there are both polyline and polygon subjects, the following clipping rules apply:
Example of clipping behaviour when mixing polyline and polygon subjects:
Usage:
var cliptype = ClipperLib.ClipType.ctIntersection; var cliptype = ClipperLib.ClipType.ctUnion; var cliptype = ClipperLib.ClipType.ctDifference; var cliptype = ClipperLib.ClipType.ctXor;
See also:
Clipper.Execute, PolyFillType
if (use_deprecated) ClipperLib.EndType = {etSquare: 0, etRound: 1, etButt: 2, etClosed: 3}; else ClipperLib.EndType = {etSquare: 0, etRound: 1, etButt: 2};
The EndType enumerator has 3 values:
Usage:
var endtype = ClipperLib.EndType.etSquare; var endtype = ClipperLib.EndType.etRound; var endtype = ClipperLib.EndType.etButt; var endtype = ClipperLib.EndType.etClosed; // only if use_deprecated
Number ioReverseSolution = 1; Number ioStrictlySimple = 2; Number ioPreserveCollinear = 4;
Usage:
var cpr = new ClipperLib.Clipper(ClipperLib.Clipper.ioStrictlySimple | ClipperLib.Clipper.ioPreserveCollinear); // or var cpr = new ClipperLib.Clipper(2 | 4);
See also:
Constructor, Clipper.PreserveCollinear, Clipper.ReverseSolution, Clipper.StrictlySimple
IntPoint IntPoint(Number X, Number Y) IntPoint IntPoint() IntPoint IntPoint(IntPoint point)
The IntPoint structure is used to represent all vertices in the Clipper Library. An "integer" storage type has been deliberately chosen to preserve numerical robustness. (Early versions of the library used floating point coordinates, but it became apparent that floating point imprecision would always cause occasional errors.)
A sequence of IntPoints are contained within a Path structure to represent a single contour.
As of version 6, IntPoint now has an optional third member 'Z'. This can be enabled by exposing (ie uncommenting) the PreProcessor define 'use_xyz'. When the Z member is used, its values will be copied to corresponding verticies in solutions to clipping operations. However, at points of intersection where there's no corresponding Z value, the value will be assigned zero unless a new value is provided by a user supplied callback function.
Users wishing to clip or offset polygons containing floating point coordinates need to use appropriate scaling when converting these values to and from IntPoints.
See also the notes on rounding.
Usage:
var point = new ClipperLib.IntPoint(10,20); // Creates object {"X":10,"Y":20} var point2 = new ClipperLib.IntPoint(); // Creates object {"X":0,"Y":0} var point3 = new ClipperLib.IntPoint(point); // Creates clone of point
See also:
Rounding, Clipper.ZFillFunction, Defines, Path, Paths
IntRect IntRect(Number left, Number top, Number right, Number bottom); IntRect IntRect(IntRect intRect); IntRect IntRect();
Structure returned by Clipper's GetBounds method.
See also:
ClipperBase.GetBounds
ClipperLib.JoinType = {jtSquare: 0, jtRound: 1, jtMiter: 2};
Edge joins may be one of three JoinTypes - jtMiter, jtSquare or jtRound. (See the image below for examples.)
Usage:
var jointype = ClipperLib.JoinType.jtSquare; var jointype = ClipperLib.JoinType.jtRound; var jointype = ClipperLib.JoinType.jtMiter;
ClipperLib.PolyFillType = {pftEvenOdd: 0, pftNonZero: 1, pftPositive: 2, pftNegative: 3};
Filling indicates regions that are inside a polygon (ie 'filled' with a brush color or pattern in a graphical display), and non-filling indicates regions outside polygons. The Clipper Library supports 4 filling rules: Even-Odd, Non-Zero, Positive and Negative.
Read more in original documentation.
Usage:
var polyfilltype = ClipperLib.PolyFillType.pftEvenOdd; var polyfilltype = ClipperLib.PolyFillType.pftNonZero; var polyfilltype = ClipperLib.PolyFillType.pftPositive; var polyfilltype = ClipperLib.PolyFillType.pftNegative;
See also:
Clipper.Execute, Orientation
Path Path()
This structure contains a sequence of IntPoint vertices defining a single contour (see also terminology). Paths may be open and represent line segments bounded by 2 or more vertices, or they may be closed and represent polygons.
Multiple paths can be grouped into a Paths structure.
Usage:
var path = new ClipperLib.Path(); // Creates an empty array [] // or var path = new Array(); // or var path = [];
See also:
Example, ClipperBase.AddPath, PolyTree, Orientation, IntPoint, Paths
Paths Paths()
This structure is fundamental to the Clipper Library. It's an array of one or more Path structures. (The Path structure contains an ordered array of vertices that make a single contour.)
Paths may open (lines), or they may closed (polygons).
Usage:
var paths = new ClipperLib.Paths(); // Creates an empty array [] // or var path = new Array(); // or var path = [];
See also:
Clipper.Execute, ClipperBase.AddPath, ClipperBase.AddPaths, OffsetPaths, IntPoint, Path
Number ClipperLib.PolyType = {ptSubject: 0, ptClip: 1};
Boolean (clipping) operations are mostly applied to two sets of Polygons, represented in this library as subject and clip polygons. Whenever Polygons are added to the Clipper object, they must be assigned to either subject or clip polygons.
UNION operations can be performed on one set or both sets of polygons, but all other boolean operations require both sets of polygons to derive meaningful solutions.
Usage:
var polytype = ClipperLib.PolyType.ptSubject; var polytype = ClipperLib.PolyType.ptClip;
See also:
ClipperBase.AddPath, ClipperBase.AddPaths, ClipType
void TZFillCallback(IntPoint Z1, IntPoint Z2, IntPoint pt);
See also:
Clipper.ZFillFunction
ClipperOffset ClipperOffset( JoinType joinType = JoinType.jtSquare, EndType endType = EndType.etSquare, Number miterLimit = 2.0, Number roundPrecision = 0.25);
The ClipperOffset constructor takes 4 optional parameters: JoinType, EndType, MiterLimit and ArcTolerance. Each parameter corresponds to a property of the same name. Only the JoinType parameter/property is relevant to every offsetting operation. EndType is only relevant when offsetting open paths. MiterLimit is only relevant when JoinType is jtMiter, and ArcTolerance is only relevant when JoinType is jtRound or when EndType is etRound.
Usage:
var co = new ClipperLib.ClipperOffset( ClipperLib.JoinType.jtSquare, ClipperLib.EndType.etSquare, 2.0, 0.25);
See also:
ArcTolerance, EndType, JoinType, MiterLimit
Number ArcTolerance
Since it would require an infinite number of vertices to perfectly represent an arc with a flattened path, this field/property specifies the accepted 'tolerance' when approximating arcs (ie the maximum distance a flattened path is allowed to deviate from the 'true' arc). While smaller tolerances increase 'smoothness' (up to a point - see below) by using more chords to represent the arc, greater tolerances do the reverse. The default ArcTolerance is 0.25 units.
Reducing tolerances below 0.25 will not improve smoothness since vertices will still be rounded to integer values. (The only way to achieve sub-integer precision is through coordinate scaling before and after clipping/offsetting.) Conversely, high degrees of precision may not only be unnecessary but may significantly slow offsetting performance when very large coordinate values are encountered (resulting in very large arc radii). It's generally advisable to increase tolerance proportional to coordinate scaling (eg when coordinate values are typically greater than ±1.0E6).
Usage:
co.ArcTolerance = 1.23;
Number EndType
The EndType can be one of three values: etSquare, etRound, etButt.
Usage:
co.EndType = ClipperLib.EndType.etSquare; co.EndType = ClipperLib.EndType.etRound; co.EndType = ClipperLib.EndType.etButt;
Number JoinType
Edge joins may be one of three JoinTypes - jtMiter, jtSquare or jtRound.
Usage:
co.JoinType = ClipperLib.JoinType.jtMiter; co.JoinType = ClipperLib.JoinType.jtSquare; co.JoinType = ClipperLib.JoinType.jtRound;
See also:
ArcTolerance, MiterLimit
Number MiterLimit
This property sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied. (Squaring truncates a miter by 'cutting it off' at 1 * delta distance from the original vertex.)
The default value for MiterLimit is 2 (ie twice delta). This is also the smallest MiterLimit that's allowed. If offsetting was allowed without any limits (ie without squaring), then offsetting at very acute angles would produce unacceptably long 'spikes'.
Usage:
co.MiterLimit = 4.0;
See also:
JoinType
void AddPath(Path path, Boolean closed);
Adds a path to a ClipperOffset object in preparation for offsetting. This method can be called multiple times.
Usage:
co.AddPath(path, true); // true for closed path
void AddPaths(Paths paths, Boolean closed);
Adds paths to a ClipperOffset object in preparation for offsetting. This method can be called multiple times.
Usage:
co.AddPaths(paths, true); // true for closed path
void Clear();
This method clears all paths from the ClipperOffset object, allowing new paths to be assigned.
Usage:
co.Clear();
void Execute(PolyTree polytree, Number delta);
This method takes two parameters. The first is the structure (either PolyTree or Paths) that will receive the result of the offset operation. The second parameter is the amount to which the supplied paths will be offset - negative delta values to shrink polygons and positive delta to expand them.
This method can be called multiple times, offsetting the same paths by different amounts (ie using different deltas).
Usage:
var subj = new ClipperLib.Paths(), solution = new ClipperLib.Paths(); subj[0] = [{"X":348,"Y":257},{"X":364,"Y":148},{"X":362,"Y":148},{"X":326,"Y":241},{"X":295,"Y":219},{"X":258,"Y":88},{"X":440,"Y":129},{"X":370,"Y":196},{"X":372,"Y":275}]; var co = new ClipperLib.ClipperOffset(ClipperLib.JoinType.jtRound); co.AddPaths(subj, true); co.Execute(solution, -7.0); //draw solution ... DrawPolygons(solution, 0x4000FF00, 0xFF009900);
PolyTree PolyTree()
Returns new PolyTree object.
PolyTree is intended as a read-only data structure that should only be used to receive solutions from polygon clipping operations. It's an alternative data structure the Paths structure which can also receive clipping solutions. Its major advantages over the Paths structure is that it properly represents the parent-child relationships of the returned polygons, and that it also differentiates between open and closed paths. However, since a PolyTree is more complex than a Paths structure, and because it's more computationally expensive to process (the Execute method being roughly 5-10% slower), it should only be used when parent-child polygon relationships are needed, or when open paths are being 'clipped'.
An empty PolyTree object can be passed as the solution parameter to a Clipper object's Execute method. Once the clipping operation is completed, this method returns with the PolyTree structure filled with data representing the solution.
Usage:
var polytree = new ClipperLib.PolyTree(); // creates PolyTree object // cpr.Execute ...
Read more in original documentation.
See also:
Clipper.Execute, PolyNode, ClosedPathsFromPolyTree, OpenPathsFromPolyTree, Paths
void polytree.Clear()
This method clears any PolyNode children contained by PolyTree the object.
Clear does not need to be called explicitly. The Clipper.Execute method that accepts a PolyTree parameter will automatically clear the PolyTree object before propagating it with new PolyNodes. Likewise, PolyTree's destructor will also automatically clear any contained PolyNodes.
See also:
Clipper.Execute
PolyNode GetFirst()
This method returns the first outer polygon contour if any, otherwise a null pointer.
This function is almost equivalent to calling Childs[0] except that when a PolyTree object is empty (has no children), calling Childs[0] would raise an out of range exception.
Usage:
var polynode = polytree.GetFirst();
See also:
PolyNode.GetNext, PolyNode.ChildCount, PolyNode.Childs
Number Total() // read only
Returns the total number of PolyNodes (polygons) contained within the PolyTree. This value is not to be confused with ChildCount() which returns the number of immediate children only (Childs) contained by PolyTree.
See also:
PolyNode.ChildCount(), PolyNode.Childs()
PolyNode PolyNode() // read only
PolyNodes are encapsulated within a PolyTree container, and together provide a data structure representing the parent-child relationships of polygon contours returned by Clipper's Execute method.
A PolyNode object represents a single polygon. Its IsHole property indicates whether it's an outer or a hole. PolyNodes may own any number of PolyNode children (Childs), where children of outer polygons are holes, and children of holes are (nested) outer polygons.
See also:
Clipper.Execute, PolyTree
PolyNode GetNext()
The returned Polynode will be the first child if any, otherwise the next sibling, otherwise the next sibling of the Parent etc.
A PolyTree can be traversed very easily by calling GetFirst() followed by GetNext() in a loop until the returned object is a null pointer ...
Usage:
var polytree = new ClipperLib.PolyTree(); //call to Clipper.Execute method here which fills 'polytree' var polynode = polytree.GetFirst(); while (polynode) { //do stuff with polynode here polynode = polynode.GetNext(); }
See also:
PolyTree.GetFirst
Number ChildCount() // read only
Returns the number of PolyNode Childs directly owned by the PolyNode object.
Usage:
var count = polynode.ChildCount();
See also:
Childs
Array < PolyNode > Childs() // read only
Array of PolyNode. Outer PolyNode childs contain hole PolyNodes, and hole PolyNode childs contain nested outer PolyNodes.
Usage:
var childs = polynode.Childs();
See also:
ChildCount
Path Contour() // read only
Returns a path list which contains any number of vertices.
Usage:
var contour = polynode.Contour();
Boolean IsHole() // read only
Returns true when the PolyNode's polygon (Contour) is a hole.
Children of outer polygons are always holes, and children of holes are always (nested) outer polygons.
The IsHole property of a PolyTree object is undefined but its children are always top-level outer polygons.
Usage:
var ishole = polynode.IsHole();
Boolean IsOpen // read only property
Returns true when the PolyNode's Contour results from a clipping operation on an open contour (path). Only top-level PolyNodes can contain open contours.
Usage:
var isopen = polynode.IsOpen;
See also:
Contour
PolyNode Parent(); read only
Returns the parent PolyNode.
The PolyTree object (which is also a PolyNode) does not have a parent and will return a null pointer.
Usage:
var parent = polynode.Parent();
By using an integer type for polygon coordinates, the Clipper Library has been able to avoid problems of numerical robustness that can cause havoc with geometric computations. Problems associated with integer rounding and their possible solutions are discussed in the original documentation.
Texts and images have been copied (with permission) from the original Clipper Documentation, with some modifications to fit the Javascript environment.
Clipper Documentation is copyright 2010-2013 Angus Johnson.
Modifications copyright 2013 Timo.