Skip to content

RectClip produces incorrect result #1095

Open

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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