How clip works in polygon union in Clipper library

Sean picture Sean · Jun 14, 2013 · Viewed 7.1k times · Source

enter image description here

I use clipper library. In the figure, red and black are clips and and green are polygons. The code is listed below. However, I do not understand why the resulting union polygon is (7 3 4 14 9 1 2 6). I assume it should be (1 4 14 9)? The number is vertex shown in the figure.

using System;
using ClipperLib;

using Polygon = System.Collections.Generic.List<ClipperLib.IntPoint>;
using Polygons = System.Collections.Generic.List<System.Collections.Generic.List<ClipperLib.IntPoint>>;

namespace ClipperLibrary_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Polygons subj = new Polygons(1);
            subj.Add(new Polygon(4));
            subj[0].Add(new IntPoint(0, 0));
            subj[0].Add(new IntPoint(0, 70));
            subj[0].Add(new IntPoint(100, 70));
            subj[0].Add(new IntPoint(100, 0));

            Polygons clip = new Polygons();
            clip.Add(new Polygon(4));
            clip[0].Add(new IntPoint(40, 0));
            clip[0].Add(new IntPoint(40, 100));
            clip[0].Add(new IntPoint(150, 100));
            clip[0].Add(new IntPoint(150, 0));

            clip.Add(new Polygon(4));
            clip[1].Add(new IntPoint(-50, 0));
            clip[1].Add(new IntPoint(-50, 100));
            clip[1].Add(new IntPoint(60, 100));
            clip[1].Add(new IntPoint(60, 0));

            Polygons solution = new Polygons();
            Clipper c = new Clipper();
            c.AddPolygons(subj, PolyType.ptSubject);
            c.AddPolygons(clip, PolyType.ptClip);

            c.Execute(ClipType.ctUnion, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

            foreach (Polygon p in solution)
            {
                Console.WriteLine("next ");
                foreach (IntPoint pt in p)
                {
                    Console.WriteLine("(" + pt.X + "; " + pt.Y + ")");
                }
            }
            //Console.WriteLine("area: " + Clipper.Area(solution[0]).ToString());
            Console.WriteLine(solution.Count);
            Console.WriteLine("right: " + c.GetBounds().right + ": left: " + c.GetBounds().left);
        }
    }
}

Edit:

If I change PolyFillType.pftEvenOdd to PolyFillType.pftNonZero, it works fine. Could anyone explain how it affects the results?

Answer

jmihalicza picture jmihalicza · Jun 14, 2013

It is because you are using the PolyFillType.pftEvenOdd filltype for both subj and clip. The specified filltype operations are performed on both input sets respectively. In your example it does nothing on subj, but clears the common part of the two rectangles of clip, giving disjoint rectangles. The union contains these two separate rectangles plus the subject unchanged.

Just change the filltype of clip to PolyFillType.pftPositive and you will get the expected result.

I used this source: