Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong result for two simple polygons #110

Open
abelramos opened this issue Dec 28, 2019 · 14 comments · May be fixed by #115
Open

Wrong result for two simple polygons #110

abelramos opened this issue Dec 28, 2019 · 14 comments · May be fixed by #115
Assignees

Comments

@abelramos
Copy link

These are my two simple polygons:

Two simple polygons

with coordinates:

[[115,96], [140,206], [120,210], [125,250], [80,300]]
[[111,228], [129,192], [309,282]]

And this is the resulting union:

Wrong resulting union

There are no vertical edges, in fact, no two points share the same x-coordinate. I believe the issue here is with the otherInOut property not being correctly computed as these are the sweep events with otherInOut set to true after the subdivision step:

Sweep events with otherInOut set to true

I also tried with the C++ code available online from the original paper, and the resulting union is the same.

@w8r
Copy link
Owner

w8r commented Dec 30, 2019

Thanks for the detailed example and the C++ reference, I will try and figure it out

@w8r w8r self-assigned this Dec 30, 2019
@jakeNiemiec
Copy link

@abelramos Until this gets fixed, I have found that adding very small (like 0.0005), pseudorandom values to the coordinates will prevent this. The problem occurs when a point falls exactly on another line. Our app has grid snapping, I can confirm that this happens all the time.

@bluenote10
Copy link
Collaborator

bluenote10 commented Jan 6, 2020

I have tested this case with polybooljs (another implementation of the Martinez algorithm) and there it seems to work:

Input:
bug_110_input

Output:
bug_110_output

So maybe it helps to have a look where the implementations differ.

@w8r
Copy link
Owner

w8r commented Jan 6, 2020

It's not exactly the same algorithm, but thanks for the reference!

@bluenote10
Copy link
Collaborator

I also tried with the C++ code available online from the original paper...

It's not exactly the same algorithm

Ah interesting, I was wondering about that already. What is this implementation here actually based on? I've found three "original" versions of the Martinez algorithm:

@w8r
Copy link
Owner

w8r commented Jan 6, 2020

it's the last one

@abelramos
Copy link
Author

@abelramos Until this gets fixed, I have found that adding very small (like 0.0005), pseudorandom values to the coordinates will prevent this. The problem occurs when a point falls exactly on another line. Our app has grid snapping, I can confirm that this happens all the time.

Exactly. I can also confirm it is not related to floating-point arithmetic and/or epsilon values, I tested the implementation with a type for rational numbers, and the issue remains.

@abelramos
Copy link
Author

I have tested this case with polybooljs

Yes, I tried with that one too. It works. However, I believe this implementation is faster than the other one, that's why I'm interested in a fix for this one.

@daef
Copy link

daef commented Jan 7, 2020

afair the other one uses only linked lists (instead of a tree), plus solid improvements don't seem to get merged for... reasons

@w8r
Copy link
Owner

w8r commented Jan 7, 2020

I would love to get some help here, I didn't have time to look at it recently

@bluenote10
Copy link
Collaborator

bluenote10 commented Jan 7, 2020

afair the other one uses only linked lists (instead of a tree)

Exactly, I came to the same conclusion here after reading the code a bit.

I would love to get some help here, I didn't have time to look at it recently

I'd like to have a look, but I don't have access to the paper :(.

@rowanwins
Copy link
Collaborator

@bluenote10 if you send me an email me at rowanwinsemius dot id dot au , then I can supply the paper

@svenboulanger
Copy link

I'm working on my own implementation of the Martinez paper, and I started there from the original implementation in C++ that they published (I need integer coordinates). Since I was having the same issue: here's what I tracked what was going wrong:

When the status line reaches point (120, 210), the line segments starting at (120,210) are incorrectly inserted between segment (111,228)-(129,192) and (80,300)-(115,96). This causes the segments to have the wrong neighbors.

So what likely needs work, is the segment comparer. I noticed that you're using a comparer somewhat similar to the C++ version so I'm guessing that's also going to apply here. When I made sure the segment comparer ordered them correctly for this one use case, the correct result was being computed.

@w8r
Copy link
Owner

w8r commented May 19, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants