FAQ

The Clipper Library

FAQ

Why does Clipper use integer coordinates, not floats?

Initially Clipper did use floating point coordinates but the clipping algorithm wasn't numerically robust. Consequently, very occasionally errors occurred which prevented Clipper from returning a solution. These issues have completely resolved since swapping to integer coordinates.

How do I use floating point coordinates with Clipper?

It's a simple task to multiply your floating point coordinates by a scaling factor (that's typically a power of 10 depending on the desired precision). Then with the solution polygons, divide the returned coordinates by this same scaling factor. Clipper accepts integer coordinates as large as +/-4.6 e18, so it can accommodate very large scaling factors.

Does Clipper handle polygons with holes?

Polygon 'holes' are implied simply by having their orientations opposite that of their container polygons.

Why are there separate fill rules for Subject and Clip polygons?

Because users may want to use different fill rules for these polygons. However it's important to note that these fill rules apply solely within subject and clip polygons to define their respective regions. These rules aren't applied to the clip operation itself where subject and clip polygons are merged into a single solution. If you wish for a fill rule to apply to the merging of subject and clip polygons as well - typically during a UNION operation, then you should UNION all the polygons as subjects without assigning any clip polygons.

Which fill rule does the boolean clipping operation use?

Perhaps the easiest way to explain what happens during clipping is to consider the following. First the subject and clip polygons are filled using their respective fill rules. With the subject polygons, assign a winding count (WC) of +1 to any filled region and a WC of 0 to any unfilled region. Do likewise with the clip polygons. Then the following winding rules apply to the clipping operation ...
  ♦ Intersection: add subject and clip regions and return those regions where WC == +2
  ♦ Union: add subject and clip regions and return those regions where WC > 0
  ♦ Difference: subtract clip from subject regions and return those regions where WC == +1
  ♦ XOR: subtract clip from subject regions and return those regions where WC != 0

Some solution polygons share a common edge. Is this a bug?

No. However Clipper tries very hard to minimize this by merging polygons that share a common edge.

I have lots of polygons that I want to 'union'. Can I do this in one operation?

Yes. Just add all the polygons as subject polygons to the Clipper object and don't assign any clip polygons.

The OffsetPolygons function is returning tiny artefacts? Could this be a bug?

The precision of the input coordinates may be a problem. The Clipper Library only operates on integer coordinates so if you need better precision than integers, scale the coordinates (eg by a factor of 10) before passing them to the OffsetPolygons function. Then it's a simple matter to reverse the scaling on the output polygons.

The OffsetPolygons function is returning unexpected results? Could this be a bug?

Most likely the orientation of the input polygons is wrong.

Is there an easy way to reverse polygon orientations?

Yes, see ReversePolygons.

Is it possible to get the offset of a line or a polyline?

Yes, just convert the polyline into a 'flat' polygon. Do this by appending to the polyline a reverse copy of the polyline while avoiding duplicate coordinates at each end: c1,c2,...,cn, c(n-1),...,c2. (You don't need to append anything if there are just two vertices forming a single line.)

var
  pts: TPolygon;
  ppts: TPolygons;
begin
  //define the polyline ...
  setlength(pts, 5);
  pts[0] := IntPoint(10,10);
  pts[1] := IntPoint(100,100);
  pts[2] := IntPoint(150,100);
  pts[3] := IntPoint(100,10);
  pts[4] := IntPoint(10,100);

  //convert the line to a 'flat' polygon ...
  len := length(pts);
  setLength(pts, len*2 -2);
  for i := 1 to len -2 do pts[len-1 +i] := pts[len-1 -i];

  //do the offsetting ...
  setlength(ppts, 1);
  ppts[0] := pts;
  ppts := OffsetPolygons(ppts, 6, jtSquare, 0);
          


 

My drawings contain lots of ellipses and arcs. How can I perform clipping operations or offsetting on these?

You'll have to convert then to polygons. Many graphics libraries have 'flatten path' routines.

See Also

OffsetPolygons, Orientation, ReversePolygons