This is Javascript Clipper 6 documentation. Unfortunately there is no documentation for Javascript Clipper 5. If you need Clipper 5 docs, please download C# Clipper 5 and check the documentation folder.
If you are migrating from Javascript Clipper 5 to 6, please read the migration guide.
[TOC]
The Javascript Clipper Library performs clipping and offsetting of both lines and polygons.
A number of features set Clipper apart from other clipping libraries:
- it accepts all types of polygons including self-intersecting ones
- it supports multiple polygon filling rules (EvenOdd, NonZero, Positive, Negative)
- it's very fast relative to other libraries
- it also performs line and polygon offsetting
- it's numerically robust
- it's free to use in both freeware and commercial applications
Current Javascript Clipper version: 6.1.3.2 (C# 6.1.3a)
Original C# version's Author & copyright: Angus Johnson. Copyright © 2010-2014 License, terms and conditions: Boost Software License
Javascript Clipper's Author & copyright: Timo. Copyright © 2012-2014 License, terms and conditions: Boost Software License
Javascript Clipper uses implementation of Tom Wu's JSBN library, which has BSD license.
- Clipping: commonly refers to the process of removing (cutting away) from a set of 2-dimensional geometric shapes those parts that are outside a rectangular 'clipping' window. This can be achieved by intersecting subject paths (lines and polygons) with the clipping rectangle. In a more general sense, the clipping window need not be rectangular but can be any type of polygon, even multiple polygons. Also, while clipping typically refers to an intersection operation, in this documentation it will refer to any one of the four boolean operations (intersection, union, difference and exclusive-or).
- Path: is an ordered sequence of vertices defining a single geometric contour that's either a line (an open path) or a polygon (a closed path).
- Contour: synonymous with path.
- Line: or polyline is an open path containing 2 or more vertices.
- Polygon: in a general sense is a two-dimensional region that's bounded by an outer closed path and containing zero to many 'holes'. However in this documentation polygon refers to a Path that's known to be closed.
- Hole: is a closed region within a polygon that's not part of the polygon. A polygon that forms the outer boundaries of a hole is called a hole polygon.
- Polygon Filling Rule: together with a list of paths, the filling rule defines those regions bounded by paths that are inside polygons (ie 'filled' in a graphical display) and those which are outside.
Distribution package contents:
The ZIP package contains the Clipper library's source code as minified and unminified. 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 6200 lines due to JSBN library and some helper functions.
Demo applications and examples are not included in the distribution package. They can be accessed here. The 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
ClipperBase is an abstract base class for Clipper. A ClipperBase object should not be instantiated directly.
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:
- 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
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();
The Clipper class encapsulates boolean operations on polygons (intersection, union, difference and XOR), which is also called polygon clipping.
Input polygons, both subject and clip sets, are passed to a Clipper object by its AddPath and AddPaths methods, and the clipping operation is performed by calling its Execute method. Multiple boolean operations can be performed on the same input polygon sets by repeat calls to Execute.
See also:
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
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
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.)
Timo: 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 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
Read more in CleanPolygon.
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 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);
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).
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).
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
IntRect GetBounds(Paths paths);
This method returns the axis-aligned bounding rectangle of paths.
Usage:
var paths = [[{"X":10,"Y":10},{"X":110,"Y":10},{"X":110,"Y":110},{"X":10,"Y":110}]]; var bounds = ClipperLib.Clipper.GetBounds(paths); // bounds is {"left":10,"top":10,"right":110,"bottom":110}
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 whenever the two polygons touch or overlap. (This function is often used to determine when polygons collide.)
See also: MinkowskiSum, Path, Paths
Paths MinkowskiSum(Path pattern, Path path, Boolean pathIsClosed) Paths MinkowskiSum(Path pattern, Paths paths, PolyFillType pathFillType, Boolean pathIsClosed)
Minkowski Addition is performed by adding each point in a polygon 'pattern' to the set of points in an open or closed path. The resulting polygon (or polygons) defines the region that the 'pattern' would pass over in moving from the beginning to the end of the 'path'.
Usage:
// 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 OffsetPaths(Paths polys, Number delta, JoinType jointype = JoinType.jtSquare, EndType endtype = EndType.etClosed, Number limit)
Deprecated. (See 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.etClosed, 0.25);
See also: ClipperOffset, ClipperOffset.JoinType, Path
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);
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.
Notes:
- Self-intersecting polygons have indeterminate orientations in which case this function won't return a meaningful value.
- The majority of 2D graphic display libraries (eg GDI, GDI+, XLib, Cairo, AGG, Graphics32) and even the SVG file format have their coordinate origins at the top-left corner of their respective viewports with their Y axes increasing downward. However, some display libraries (eg Quartz, OpenGL) have their coordinate origins undefined or in the classic bottom-left position with their Y axes increasing upward.
- For Non-Zero filled polygons, the orientation of holes must be opposite that of outer polygons.
- For closed paths (polygons) in the solution returned by Clipper's Execute method, their orientations will always be true for outer polygons and false for hole polygons (unless the ReverseSolution property has been enabled).
Usage:
var orientation = ClipperLib.Clipper.Orientation(polygon);
See also: Area, Clipper.ReverseSolution, Path
Number PointInPolygon(IntPoint pt, Path poly)
Returns 0 if false, -1 if pt is on poly and +1 if pt is in poly.
Usage:
var poly = [{X:10,Y:10},{X:110,Y:10},{X:110,Y:110},{X:10,Y:110}]; var pt = new ClipperLib.IntPoint(50,50); var inpoly = ClipperLib.Clipper.PointInPolygon(pt, poly); // inpoly is 1, which means that pt is in polygon
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);
// Call Path.reverse().
Reverses the vertex order (and hence orientation) in a path.
Usage:
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}]]
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.
Usage:
// 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 SimplifyPolygon, but the parameter is of type Paths.
Usage:
// 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
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:
- AND (intersection) - create regions where both subject and clip polygons are filled
- OR (union) - create regions where either subject or clip polygons (or both) are filled
- NOT (difference) - create regions where subject polygons are filled except where clip * polygons are filled
- XOR (exclusive or) - create regions where either subject or clip polygons are filled but not where both are filled
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:
- union operations - polylines will be clipped by any overlapping polygons so that non-overlapped portions will be returned in the solution together with the union-ed polygons
- intersection, difference and xor operations - polylines will be clipped only by 'clip' polygons and there will be not interaction between polylines and subject polygons.
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, Clipper.Execute, PolyFillType
ClipperLib.EndType = {etOpenSquare: 0, etOpenRound: 1, etOpenButt: 2, etClosedLine: 3, etClosedPolygon: 4 };
The EndType enumerator has 5 values:
- etOpenSquare: Ends are squared off and extended delta units
- etOpenRound: Ends are rounded off and extended delta units
- etOpenButt: Ends are squared off with no extension.
- etClosedLine: Ends are joined using the JoinType value and the path filled as a polyline
- etClosedPolygon: Ends are joined using the JoinType value and the path filled as a polygon etOpenSingle: Offsets an open path in a single direction. Planned for a future update.
Note: With etClosedPolygon and etClosedLine types, the path closure will be the same regardless of whether or not the first and last vertices in the path match.
Usage:
var endtype = ClipperLib.EndType.etOpenSquare; var endtype = ClipperLib.EndType.etOpenRound; var endtype = ClipperLib.EndType.etOpenButt; var endtype = ClipperLib.EndType.etClosedLine; var endtype = ClipperLib.EndType.etClosedPolygon;
See also: ClipperOffset.AddPath, ClipperOffset.AddPaths
if (use_deprecated) ClipperLib.EndType_ = {etSquare: 0, etRound: 1, etButt: 2, etClosed: 3};
Deprecated. See ClipperOffset and EndType.
The EndType_ enumerator has 4 values:
- etSquare: Ends are squared off at exactly delta units
- etRound: Ends are rounded off at exactly delta units
- etButt: Ends are squared off abruptly
- etClosed: Ends are joined using the JoinType value and the path filled as a polygon.
Usage:
var endtype = ClipperLib.EndType_.etSquare; var endtype = ClipperLib.EndType_.etRound; var endtype = ClipperLib.EndType_.etButt; var endtype = ClipperLib.EndType_.etClosed;
ExPolygon ExPolygon();
Creates an instance of ExPolygon object.
This is not anymore in the original Clipper, but in JS version we provide it to ensure backward compatibility.
Usage:
var expolygon = new ClipperLib.ExPolygon();
See also: PolyTreeToExPolygons, ExPolygonsToPaths
ExPolygons ExPolygons();
Creates an instance of ExPolygons object ie array.
This is not anymore in the original Clipper, but in JS version we provide it to ensure backward compatibility.
Usage:
var expolygons = new ClipperLib.ExPolygons();
See also: PolyTreeToExPolygons, ExPolygonsToPaths
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: GetBounds
ClipperLib.JoinType = {jtSquare: 0, jtRound: 1, jtMiter: 2};
When adding paths to a ClipperOffset object via the AddPaths method, the joinType parameter may be one of three types - jtMiter, jtSquare or jtRound.
- jtMiter: There's a necessary limit to mitered joins since offsetting edges that join at very acute angles will produce excessively long and narrow 'spikes'. To contain these potential spikes, the ClipperOffset object's MiterLimit property specifies a maximum distance that vertices will be offset (in multiples of delta). For any given edge join, when miter offsetting would exceed that maximum distance, 'square' joining is applied.
- jtRound: While flattened paths can never perfectly trace an arc, they are approximated by a series of arc chords (see ClipperObject's ArcTolerance property).
- jtSquare: Squaring is applied uniformally at all convex edge joins at 1 × delta.
Usage:
var jointype = ClipperLib.JoinType.jtSquare; var jointype = ClipperLib.JoinType.jtRound; var jointype = ClipperLib.JoinType.jtMiter;
See also: ClipperOffset, AddPaths, ArcTolerance, MiterLimit
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: Overview, 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 paths = new Array(); // or var paths = [];
See also: Clipper.Execute, ClipperBase.AddPath, ClipperBase.AddPaths, OffsetPaths, IntPoint, Path
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.
The simplest filling rule is Even-Odd filling. Given a group of polygons and starting from a point outside, whenever a contour is crossed either filling starts if it had stopped or it stops if it had started. For example, given a single rectangular polygon, when its first (eg left) edge is crossed filling starts and we're inside the polygon. Filling stops again when the next (eg right) edge is crossed.
With the exception of Even-Odd filling, all other filling rules rely on edge direction and winding numbers to determine filling. Edge direction is determined by the order in which vertices are declared when constructing a polygon. Edge direction is used to determine the winding numbers of polygon regions and subregions.
The winding number for any given polygon sub-region can be derived by:
- starting with a winding number of zero
- from a point (P1) that's outside all polygons, draw an imaginary line to a point that's inside a given sub-region (P2)
- while traversing the line from P1 to P2, for each polygon edge that crosses the line from right to left increment the winding number, and for each polygon edge that crosses the line from left to right decrement the winding number.
- Once you arrive at the given sub-region you have its winding number.
Even-Odd (Alternate): Odd numbered sub-regions are filled, while even numbered sub-regions are not. Non-Zero (Winding): All non-zero sub-regions are filled. Positive: All sub-regions with winding counts > 0 are filled. Negative: All sub-regions with winding counts < 0 are filled.
By far the most widely used fill rules are Even-Odd (aka Alternate) and Non-Zero (aka Winding). Most graphics rendering libraries (AGG, Android Graphics, Cairo, GDI+, OpenGL, Quartz 2D etc) and vector graphics storage formats (SVG, Postscript, Photoshop etc) support both these rules. However some libraries (eg Java's Graphics2D) only support one fill rule. Android Graphics and OpenGL are the only libraries (that I'm aware of) that support multiple filling rules.
It's useful to note that edge direction has no affect on a winding number's odd-ness or even-ness. (This is why orientation is ignored when the Even-Odd rule is employed.)
The direction of the Y-axis does affect polygon orientation and edge direction. However, changing Y-axis orientation will only change the sign of winding numbers, not their magnitudes, and has no effect on either Even-Odd or Non-Zero filling.
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
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 ZFillCallback(IntPoint Z1, IntPoint Z2, IntPoint pt);
See also: Clipper.ZFillFunction
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.
A PolyTree object is a container for any number of PolyNode children, with each contained PolyNode representing a single polygon contour (either an outer or hole polygon). PolyTree itself is a specialized PolyNode whose immediate children represent the top-level outer polygons of the solution. (Its own Contour property is always empty.) The contained top-level PolyNodes may contain their own PolyNode children representing hole polygons that may also contain children representing nested outer polygons etc. Children of outers will always be holes, and children of holes will always be outers.
PolyTrees can also contain open paths. Open paths will always be represented by top level PolyNodes. Two functions are provided to quickly separate out open and closed paths from a polytree - ClosedPathsFromPolyTree and OpenPathsFromPolyTree.
polytree: Contour = () ChildCount = 1 Childs[0]: Contour = ((10,10),(100,10),(100,100),(10,100)) IsHole = False ChildCount = 1 Childs[0]: Contour = ((20,20),(20,90),(90,90),(90,20)) IsHole = True ChildCount = 2 Childs[0]: Contour = ((30,30),(50,30),(50,50),(30,50)) IsHole = False ChildCount = 0 Childs[1]: Contour = ((60,60),(80,60),(80,80),(60,80)) IsHole = False ChildCount = 0 |