Skip to content

Unexpected result from Union of Paths64 #1085

@egarzago

Description

@egarzago

While using RectClip, I encountered an odd result and traced it down to a union of the clipped paths. In some instances, the union of several subjects produces a zero-width bridge on the resulting polygon. It seems that performing a second union directly after the result of the first one solves the issue. Here's a minimal reproduction of the issue:

#include <clipper2/clipper.h>
#include <iostream>

namespace
{
    void print_paths(const Clipper2Lib::Paths64& paths)
    {
        for (const auto& path : paths)
        {
            std::cout << "Path with " << path.size() << " points: ";
            for (const auto& pt : path)
            {
                std::cout << "(" << pt.x << "," << pt.y << ") ";
            }
            std::cout << "\n";
        }
    }
}  // namespace

int main()
{
    Clipper2Lib::Paths64 subject;

    subject.push_back(
        {{420, -270}, {500, 0}, {470, 100}, {0, 100}, {0, -483}, {207, -454}}
    );
    subject.push_back(
        {{0, 100}, {370, 100}, {400, 0}, {336, -216}, {166, -363}, {0, -386}}
    );
    subject.push_back(
        {{252, -162}, {300, 0}, {270, 100}, {0, 100}, {0, -289}, {124, -272}}
    );
    subject.push_back(
        {{0, 100}, {170, 100}, {200, 0}, {168, -108}, {83, -181}, {0, -192}}
    );

    auto first_union = Clipper2Lib::Union(
        subject,
        Clipper2Lib::FillRule::NonZero
    );

    std::cout << "First union result has " << first_union.size() << " paths and is: \n";
    print_paths(first_union);

    std::cout << "Performing second union on the first union result...\n";
    auto second_union = Clipper2Lib::Union(
        first_union,
        Clipper2Lib::FillRule::NonZero
    );
    std::cout << "Second union result has " << second_union.size() << " paths and is: \n";
    print_paths(second_union);

    return 0;
}
First union result has 1 paths and is: 
Path with 21 points: (200,0) (168,-108) (83,-181) (0,-192) (0,-289) (0,-483) (207,-454) (420,-270) (500,0) (470,100) (370,100) (400,0) (336,-216) (166,-363) (0,-386) (0,-289) (124,-272) (252,-162) (300,0) (270,100) (170,100) 
Performing second union on the first union result...
Second union result has 2 paths and is: 
Path with 10 points: (0,-289) (124,-272) (252,-162) (300,0) (270,100) (170,100) (200,0) (168,-108) (83,-181) (0,-192) 
Path with 10 points: (207,-454) (420,-270) (500,0) (470,100) (370,100) (400,0) (336,-216) (166,-363) (0,-386) (0,-483) 

These are the original Paths:
Image

This is the result after the first Union (single Path64 output with a zero-width bridge, not sure if that counts as a self-intersection for Clipper2):
Image

And this is the result after the second union (which is the result I expected from the first one):
Image

Using Windows MSVC 19.44 and clipper2/2.0.1 from conancenter https://conan.io/center/recipes/clipper2

Thank you for all the great work on Clipper2!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions