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

fix(polygon): Catch edge case where self-intersecting reads as convex #412

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions ladybug_geometry/geometry2d/polygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,17 +404,16 @@ def is_self_intersecting(self):
"""
if self._is_self_intersecting is None:
self._is_self_intersecting = False
if self.is_convex is False:
_segs = self.segments
for i, _s in enumerate(_segs[1: len(_segs) - 1]):
_skip = (i, i + 1, i + 2)
_other_segs = [x for j, x in enumerate(_segs) if j not in _skip]
for _oth_s in _other_segs:
if _s.intersect_line_ray(_oth_s) is not None: # intersection!
self._is_self_intersecting = True
break
if self._is_self_intersecting is True:
_segs = self.segments
for i, _s in enumerate(_segs[1: len(_segs) - 1]):
_skip = (i, i + 1, i + 2)
_other_segs = [x for j, x in enumerate(_segs) if j not in _skip]
for _oth_s in _other_segs:
if _s.intersect_line_ray(_oth_s) is not None: # intersection!
self._is_self_intersecting = True
break
if self._is_self_intersecting is True:
break
return self._is_self_intersecting

@property
Expand Down
17 changes: 17 additions & 0 deletions tests/polygon2d_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,23 @@ def test_is_self_intersecting():
assert polygon_2.is_self_intersecting


def test_is_self_intersecting_complex_clockwise():
"""Test the is_self_intersecting property on a more complex shape."""
pts_3 = (
(355.665006, -49.844883),
(298.354434, 4.142452),
(280.207456, 59.649202),
(336.988767, 88.694148),
(348.680933, 44.475185),
(342.255592, 52.129292),
(373.115776, 106.898085),
(421.261481, 55.706056),
(355.665006, -49.844883)
)
polygon = Polygon2D.from_array(pts_3)
assert polygon.is_self_intersecting


def test_is_valid():
"""Test the is_valid property."""
pts_1 = (Point2D(0, 0), Point2D(2, 0), Point2D(2, 2))
Expand Down
Loading