Menu

#27 Union problem

1.0
open
nobody
None
2019-07-19
2019-07-18
Jan
No

Thanks a lot for this great library I've noticed some problems when using union, in particular on polygons with holes. I was able to repro on Demo:

Custom poly line:
[[100,100, 200,100, 170,150, 100,40, 120,40, 190,150]]

Offsetting: OpenRound, PolyType: Subject, Join: Round, Delta: 4.000

And compare Clip type: No versus Clip type: Union
Desired behavior: we're just unioning the polygon (produced by offsetting a line) with itself so it shouldn't change.

1 Attachments

Discussion

  • Jan

    Jan - 2019-07-18

    On the other hand I can't reproduce it in the c# version of the library:
    If I replace contents of GenerateRandomPolygon with

            var subj = new Polygon(new IntPoint[] {new IntPoint(10000, 10000), new IntPoint(20000, 10000),
                new IntPoint(17000, 15000), new IntPoint(10000, 4000), new IntPoint(12000, 4000), new IntPoint(19000, 15000)});
            var co = new ClipperOffset();
            co.AddPath(subj, JoinType.jtRound, EndType.etOpenRound);
            co.Execute(ref subjects, 400);
    

    (crude, I know)
    It doesn't do anything strange when choosing union.

     
  • Jan

    Jan - 2019-07-18

    Hi Timo, thanks for responding so quickly. You're right it's something weird in the demo. However, I'm still facing the issue in my actual code. I've tried to simplify the paths. To reproduce, copy this in to starter_offset.html:

    var p1 = [[{"X":703,"Y":594},{"X":703,"Y":719},{"X":827,"Y":1960}]];
    var p2  = [[{"X":827,"Y":2029},{"X":827,"Y":2098},{"X":1199,"Y":3015}]];
    ClipperLib.JS.ScaleUpPaths(p1, 5);
    ClipperLib.JS.ScaleUpPaths(p2, 5);
    
    var co = new ClipperLib.ClipperOffset(2, 0.25);
    co.AddPaths(p1, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etOpenRound);
    var polys1 = new ClipperLib.Paths();
    co.Execute(polys1, 400);
    
    var co = new ClipperLib.ClipperOffset(2, 0.25);
    co.AddPaths(p2, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etOpenRound);
    var polys2 = new ClipperLib.Paths();
    co.Execute(polys2, 400);
    
    
    var solution = new ClipperLib.Paths();
    var c = new ClipperLib.Clipper();
    c.AddPaths(polys1, ClipperLib.PolyType.ptSubject, true);
    c.AddPaths(polys2, ClipperLib.PolyType.ptSubject, true);
    c.Execute(ClipperLib.ClipType.ctUnion, solution);
    
    
    var svg = '<svg style="background-color:#dddddd" width="400" height="400">';
    svg += '<path stroke="black" fill="yellow" stroke-width="2" d="' + paths2string(solution, 100) + '"/>';
    svg += '</svg>';
    document.getElementById("svgcontainer").innerHTML = svg;
    

    or this for the c# library

            var p1 = new Polygon(new IntPoint[] { new IntPoint(703,594), new IntPoint(703,719), new IntPoint(827,1960)});
            var p2 = new Polygon(new IntPoint[] { new IntPoint(827,2029), new IntPoint(827,2098), new IntPoint(1199,3015)});
    
            var co = new ClipperLib.ClipperOffset(2, 0.25);
            co.AddPath(p1, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etOpenRound);
            var polys1 = new Polygons();
            co.Execute(ref polys1, 400);
    
            co = new ClipperLib.ClipperOffset(2, 0.25);
            co.AddPath(p2, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etOpenRound);
            var polys2 = new Polygons();
            co.Execute(ref polys2, 400);
    
            var c = new ClipperLib.Clipper();
            c.AddPaths(polys1, ClipperLib.PolyType.ptSubject, true);
            c.AddPaths(polys2, ClipperLib.PolyType.ptSubject, true);
            c.Execute(ClipperLib.ClipType.ctUnion, subjects);
    

    they both produce the same (so there is no bug in your library), but I don't like the output. I have two lines, produce 2 polygons that are line offset of these lines and union them. I expect to get one polygon in return without any holes. But for some reason the area where they overlap is returned as a second (hole) polygon.
    Can you help me understand what am I doing wrong?

     
  • Jan

    Jan - 2019-07-19

    I've found the problem. Even though the documentation says

    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. https://sourceforge.net/p/jsclipper/wiki/documentation/#clipperlibpolytype

    you really need both subject and clip sets. So, the fix was to add the second polygon as ptClip and then the union works correctly

     

Log in to post a comment.