Skip to content

Redundant points and undetected overlaps #10

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

Open
Thorreke opened this issue Feb 22, 2025 · 1 comment
Open

Redundant points and undetected overlaps #10

Thorreke opened this issue Feb 22, 2025 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@Thorreke
Copy link

I have a set of rectangles that I want to convert into a single polygon

g = [[(320, -60), (320, 375), (-60, 375), (-60, -60)], [(680, -60), (680, 375), (275, 375), (275, -60)], [(955, 105), (955, 375), (635, 375), (635, 105)], [(1360, -10), (1360, 725), (910, 725), (910, -10)], [(1360, 325), (1360, 725), (855, 725), (855, 325)], [(1360, 680), (1360, 1055), (855, 1055), (855, 680)], [(900, 325), (900, 480), (-60, 480), (-60, 325)], [(900, 435), (900, 880), (725, 880), (725, 435)], [(330, 435), (330, 880), (-60, 880), (-60, 435)], [(390, 700), (390, 880), (-60, 880), (-60, 700)], [(390, 567), (390, 747), (-60, 747), (-60, 567)], [(390, 435), (390, 615), (-60, 615), (-60, 435)], [(775, 435), (775, 880), (345, 880), (345, 435)], [(585, 835), (585, 1145), (140, 1145), (140, 835)], [(190, 835), (190, 1145), (-60, 1145), (-60, 835)]]

shapes = [Primitive.polygon(v) for v in g]

But this operation fails:
combined = reduce(lambda x,y: x|y, shapes)

Traceback (most recent call last):
File "/snap/pycharm-community/439/plugins/python-ce/helpers/pydev/pydevconsole.py", line 364, in runcode
coro = func()
File "", line 1, in
File "", line 1, in
File "/mypath/.venv/lib/python3.10/site-packages/shapepy/shape.py", line 560, in or
new_jordans = FollowPath.or_shapes(self, other)
File "/mypath/.venv/lib/python3.10/site-packages/shapepy/shape.py", line 337, in or_shapes
new_jordans = FollowPath.follow_path(all_jordans, indexs)
File "/mypath/.venv/lib/python3.10/site-packages/shapepy/shape.py", line 279, in follow_path
jordan = FollowPath.indexs_to_jordan(jordans, indices_matrix)
File "/mypath/.venv/lib/python3.10/site-packages/shapepy/shape.py", line 259, in indexs_to_jordan
new_jordan = JordanCurve.from_segments(beziers)
File "/mypath/.venv/lib/python3.10/site-packages/shapepy/jordancurve.py", line 132, in from_segments
assert prev_end_point == next_start_point
AssertionError

Closer inspection reveals some strange things are going on:

For example the following produces a correct result, however there are extra points in the shape.

s = reduce(lambda x,y:x|y,shapes[3:5])
print(s)

Simple Shape of area 352750.00 with vertices:
[[1360. -10.]
[1360. 325.]
[1360. 725.]
[ 910. 725.]
[ 855. 725.]
[ 855. 325.]
[ 910. 325.]
[ 910. -10.]]

This one produces a loop in the outline:

s = reduce(lambda x,y:x|y,shapes[1:3])
print(s)

Simple Shape of area 262575.00 with vertices:
[[680. -60.]
[680. 105.]
[955. 105.]
[955. 375.]
[680. 375.]
[635. 375.]
[635. 105.]
[680. 105.]
[680. 375.]
[635. 375.]
[320. 375.]
[275. 375.]
[275. -60.]
[320. -60.]]

And sometimes it does not even detect the rectangles are overlapping:

s = reduce(lambda x,y:x|y,shapes[0:2])
print(s)
for j in s.jordans:
         print(j)

Disjoint shape with total area 341475.0 and 2 subshapes
Jordan Curve of degree 1 and vertices
((680, -60), (680, 105), (680, 375), (635, 375), (320, 375), (275, 375), (275, -60), (320, -60))
Jordan Curve of degree 1 and vertices
((275, 375), (-60, 375), (-60, -60), (275, -60), (320, -60), (320, 375))

@carlos-adir
Copy link
Contributor

Thank you for the issue. It helps me improving the package !

Indeed, the current implementation has problems when operation with shapes that shares the same edge.
Showing the positions of your points gives that:

Code to generate image
from matplotlib import pyplot as plt
import numpy as np

rectangles = [
    [(320, -60), (320, 375), (-60, 375), (-60, -60)],
    [(680, -60), (680, 375), (275, 375), (275, -60)],
    [(955, 105), (955, 375), (635, 375), (635, 105)],
    [(1360, -10), (1360, 725), (910, 725), (910, -10)],
    [(1360, 325), (1360, 725), (855, 725), (855, 325)],
    [(1360, 680), (1360, 1055), (855, 1055), (855, 680)],
    [(900, 325), (900, 480), (-60, 480), (-60, 325)],
    [(900, 435), (900, 880), (725, 880), (725, 435)],
    [(330, 435), (330, 880), (-60, 880), (-60, 435)],
    [(390, 700), (390, 880), (-60, 880), (-60, 700)],
    [(390, 567), (390, 747), (-60, 747), (-60, 567)],
    [(390, 435), (390, 615), (-60, 615), (-60, 435)],
    [(775, 435), (775, 880), (345, 880), (345, 435)],
    [(585, 835), (585, 1145), (140, 1145), (140, 835)],
    [(190, 835), (190, 1145), (-60, 1145), (-60, 835)],
]

# plot points
all_points = set()
for rectangle in rectangles:
    all_points |= set(tuple(rectangle))
all_points = np.array(tuple(all_points))
for i, rectangle in enumerate(rectangles):
    points = np.array(list(rectangle) + [rectangle[0]])
    plt.plot(points[:, 0], points[:, 1], label=str(i))
plt.scatter(all_points[:, 0], all_points[:, 1], color="k")
plt.gca().set_aspect("equal")
plt.show()

Image

In fact, with only the frist two rectangles it gives the wrong result. The union gives a DisjointShape with jordans:

Jordan Curve of degree 1 and vertices
((680, -60), (680, 375), (320, 375), (275, 375), (275, -60), (320, -60))
Jordan Curve of degree 1 and vertices
((275, 375), (-60, 375), (-60, -60), (275, -60), (320, -60), (320, 375))

Image

I'm working on this to solve the issue.

@carlos-adir carlos-adir added the bug Something isn't working label Mar 26, 2025
@carlos-adir carlos-adir self-assigned this Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants