Skip to content

RectClip produces incorrect result #1095

@egarzago

Description

@egarzago

Thank you for Clipper2!

Woking with RectClip found some instances that produces a valid polygon, but with the incorrect result (a sliver is present). I was able to recreate the issue on a simple case when intersecting a (rotated rectangle) with a Rect64.

Here's the code to reproduce (C++20 on MSVC, using the conan package for clipper2/2.0.1:

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

namespace clipper = Clipper2Lib;

int main()
{
    clipper::Rect64 rect(19669914, -390330085, 24669914, -385330085);

    clipper::Paths64 polygon;
    polygon.push_back(
        {{8821540, -379573701},
         {27274660, -333900624},
         {72947737, -352353745},
         {54494616, -398026821}}
    );

    auto result = clipper::RectClip(
        rect,
        polygon
    );

    for (const auto& path : polygon)
    {
        std::cout << "Initial path:\n";
        for (const auto& pt : path)
        {
            std::cout << "(" << pt.x << ", " << pt.y << ")\n";
        }
    }

    for (const auto& path : result)
    {
        std::cout << "Clipped path:\n";
        for (const auto& pt : path)
        {
            std::cout << "(" << pt.x << ", " << pt.y << ")\n";
        }
    }

    return 0;
}

Output:

Initial path:
(8821540, -379573701)
(27274660, -333900624)
(72947737, -352353745)
(54494616, -398026821)
Clipped path:
(24669914, -390330085)
(24669913, -385976859)
(23069090, -385330085)
(24669914, -385330085)

Here are the plotted Inputs/outputs

Image

And this is the sliver that gets created:

Image

Zooming in, it seems that the intersection with the boundary of the Rect64 is one unit off (inwards):

Image

Unsure if this is of any help, but I suspect the root cause is in rounding when getting the intersection between the input polygon and the Rect64. Perhaps one could ensure that in GetIntersection (

inline bool GetIntersection(const Path64& rectPath,
) and GetSegmentIntersection the resulting intersection point is guaranteed to touch the boundary of the Rect64 based on the input Location, i.e. if Location::Left -> ip.x = rectPath[0].x, and so on.

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