-
Notifications
You must be signed in to change notification settings - Fork 109
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
Predicates2 new methods addition #1153
base: main
Are you sure you want to change the base?
Changes from 6 commits
2ba8533
ed2229b
a10d0ad
99ec0cb
1fe82a0
4dc265e
95c1e59
55f2921
2d569b6
40accd6
cd8e8e2
0f5a7f9
d2afaf5
bf59b37
2572319
78daeab
15a2be9
6433bb7
fabde09
8226ba7
b1d3ddf
6b7c3e8
6126fed
05499b1
5c38118
bc3714f
ebecc85
fcd0051
31fce1b
338400b
53c9b4e
900b7e9
7a3eba9
d04e282
f32cb8c
aaf385f
d410c39
c41df18
413534f
b46a68a
a7172ca
7361ff3
bb1a35e
9ba5f18
9c15e60
c57c46a
8500d85
f5667d5
bf3782a
ca1283b
fb4b358
1b56827
aec4329
162d859
b8b2025
815f446
f6acae3
564064b
1cf75cd
6c7929d
73104f0
be377c2
1b7178f
0913eb8
787973a
a23028c
59cff0d
05139fa
76e6f2e
e9faac1
abd90b6
85d3837
d56da2c
d1c930b
312d922
7fa21a1
e07ff65
4f9ec40
c8dcf25
a3959c5
b80c5bc
0aa6f52
3f579e7
ad47fe0
bc5d3a7
a4e7669
2e508d1
2c0964b
d5f0015
23a04c7
31980aa
0f13949
f223f4e
d80bfd6
2796660
aeba839
2194404
9181386
ec6d0ab
97de464
05bac88
39551af
3ac322b
b7c17d4
b896caf
a058de4
11125e7
6846a17
885bcb2
f77cb16
2ea9af2
af3eea5
6ce2bd5
40c5384
8710fe2
97ad624
e2cbe58
fb81bfa
c96d6e1
649a1fb
e536857
a84b33b
ab62d64
aac40f2
7080f90
6d147bf
93296b7
c58b67d
6426c7e
49b996b
897de99
bf91e71
5080734
aef5eab
7a73089
62346e0
5126faa
d4e6d76
d3711ae
93fb7ee
9db8a26
4dca7bd
ef0a9fe
98c1255
ce59008
a986c74
316ea7e
904054f
c86a3de
86300f1
9483518
1fda2d7
e4f1f8c
35f0ea6
d885264
226bbb5
1b47ed3
bba6912
727e4f4
fcde961
a0d3204
5d0823b
f3e84e3
8ff9fa2
ad8c262
d298244
c29734a
c0b5cdf
b63a00b
5ba87c5
cf127c2
09080ad
5531210
b4f8546
e5653ee
3f39b23
e7fb12b
a4da892
5b17181
288b3b0
56200e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,3 +36,4 @@ | |
- Chen Kasirer <<[email protected]>> [@chenkasirer](https://github.com/chenkasirer) | ||
- Nickolas Maslarinos <<[email protected]>> [@nmaslarinos](https://github.com/nmaslarinos) | ||
- Katerina Toumpektsi <<[email protected]>> [@katarametin](https://github.com/katarametin) | ||
- Joelle Baehr-Bruyere <<[email protected]>> [@baehrjo](https://github.com/baehrjo) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ | |
"is_point_in_convex_polygon_xy", | ||
"is_point_in_circle_xy", | ||
"is_polygon_in_polygon_xy", | ||
"polygon_to_polygon_relationship_xy", | ||
"point_to_polygon_relationship_xy", | ||
"is_intersection_polygon_polygon_xy", | ||
"is_intersection_line_line_xy", | ||
"is_intersection_segment_segment_xy", | ||
] | ||
|
@@ -383,7 +386,7 @@ def is_polygon_in_polygon_xy(polygon1, polygon2): | |
for i in range(len(polygon1)): | ||
line = [polygon1[-i], polygon1[-i - 1]] | ||
for j in range(len(polygon2)): | ||
line_ = [polygon2[-j], polygon2[j - 1]] | ||
line_ = [polygon2[-j], polygon2[-j - 1]] | ||
if is_intersection_segment_segment_xy(line, line_): | ||
return False | ||
for pt in polygon2: | ||
|
@@ -392,6 +395,118 @@ def is_polygon_in_polygon_xy(polygon1, polygon2): | |
return False | ||
|
||
|
||
def polygon_to_polygon_relationship_xy(polygon1, polygon2): | ||
"""Determine if a polygon (polygon1) is inside, intersects, is outside or contains another polygon (polygon2) on the XY-plane. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it required that the polygons are convex? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not required, the methods works for any (XY) polygon. In the is_polygon_in_polygon method, there's a convexity check at the beginning because if both polygons are convex then checking that all points of one polygon are contained in the other is enough and faster, while without that convexity, we have to check that both all points are inside and no edges intersect. In polygon_to_polygon_relationship, we need the intersection check anyway as we deduct information from it for other relationship than containment, that's why I don't check convexity at the begenning. Polygon_to_polygon_relationship first checks for intersection, then for containment, and if not deducts that the polygon is outside instead of calling separate methods. Separate methods ('is_polygon_in_polygon_xy', 'is_intersection_polygon_polygon_xy', ...) are still useful when looking for a True/False answer only but calling them inside polygon_to_polygon_relationship would run several times the same pieces of code. |
||
|
||
Parameters | ||
---------- | ||
polygon1 : sequence[point] | :class:`~compas.geometry.Polygon` | ||
List of XY(Z) coordinates of points representing the locations of the corners of the polygon to examine the position regarding the boundary polygon (Z will be ignored). | ||
The vertices are assumed to be in order. The polygon is assumed to be closed: | ||
the first and last vertex in the sequence should not be the same. | ||
polygon2 : sequence[point] | :class:`~compas.geometry.Polygon` | ||
List of XY(Z) coordinates of points representing the locations of the corners of the boundary polygon (Z will be ignored). | ||
The vertices are assumed to be in order. The polygon is assumed to be closed: | ||
the first and last vertex in the sequence should not be the same. | ||
|
||
Returns | ||
------- | ||
int | ||
1 if polygon1 is inside polygon2. | ||
0 if polygon1 intersects polygon2. | ||
-1 if polygon1 is outside polygon2. | ||
-2 if polygon1 contains polygon2 (polygon2 is inside polygon1). | ||
""" | ||
for i in range(len(polygon1)): | ||
line1 = [polygon1[i], polygon1[i - 1]] | ||
for j in range(len(polygon2)): | ||
line2 = [polygon2[j], polygon2[j - 1]] | ||
if is_intersection_segment_segment_xy(line1, line2): | ||
return 0 | ||
Comment on lines
+400
to
+405
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we not replace this by a call to |
||
for pt in polygon1: | ||
if is_point_in_polygon_xy(pt, polygon2): | ||
return 1 | ||
if is_point_in_polygon_xy(polygon2.centroid, polygon1): | ||
return -2 | ||
Comment on lines
+406
to
+410
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why the different approach here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean different because of calling other existing methods inside the loop here ? |
||
return -1 | ||
|
||
|
||
def point_to_polygon_relationship_xy(point, polygon, tolerance=10**-6): | ||
"""Determine if a point is inside, outside or on the boundary (with tolerance) of a polygon in the XY-plane. | ||
|
||
Parameters | ||
---------- | ||
point : [float, float, float] | :class:`~compas.geometry.Point` | ||
XY(Z) coordinates of a point (Z will be ignored). | ||
polygon : sequence[point] | :class:`~compas.geometry.Polygon` | ||
List of XY(Z) coordinates of points representing the locations of the corners of the boundary polygon (Z will be ignored). | ||
The vertices are assumed to be in order. The polygon is assumed to be closed: | ||
the first and last vertex in the sequence should not be the same. | ||
|
||
Returns | ||
------- | ||
int | ||
1 if point is inside polygon. | ||
0 if point is on the boundary of polygon. | ||
-1 if point is outside polygon. | ||
""" | ||
x, y = point[0], point[1] | ||
polygon = [(p[0], p[1]) for p in polygon] # make 2D | ||
flag = -1 | ||
for i in range(-1, len(polygon) - 1): | ||
x1, y1 = polygon[i] | ||
x2, y2 = polygon[i + 1] | ||
segment = ([x1, y1], [x2, y2]) | ||
if is_point_on_segment_xy(point, segment, tolerance): | ||
return 0 | ||
elif y > min(y1, y2): | ||
if y <= max(y1, y2): | ||
if x <= max(x1, x2): | ||
if y1 != y2: | ||
xinters = (y - y1) * (x2 - x1) / (y2 - y1) + x1 | ||
if x1 == x2 or x <= xinters: | ||
flag = -flag | ||
return flag | ||
Comment on lines
+433
to
+449
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems to be a combination of |
||
|
||
|
||
def is_intersection_polygon_polygon_xy(polygon1, polygon2): | ||
"""Determines if two polygons intersect, assuming they lie in the XY plane. | ||
|
||
Parameters | ||
---------- | ||
polygon1 : sequence[point] | :class:`~compas.geometry.Polygon` | ||
A Polygon lying in the XY. | ||
polygon2 : sequence[point] | :class:`~compas.geometry.Polygon` | ||
A Polygon lying in the XY. | ||
|
||
Returns | ||
------- | ||
bool | ||
True if the polygons intersect. False if they don't. | ||
|
||
Examples | ||
-------- | ||
>>> from compas.geometry import Polygon | ||
>>> polygon1 = Polygon([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]) | ||
>>> polygon2 = Polygon([[0.5, 0.5], [1.5, 0.5], [1.5, 1.5], [0.5, 1.5]]) | ||
>>> is_intersection_polygon_polygon_xy(polygon1, polygon2) | ||
True | ||
|
||
>>> from compas.geometry import Polygon | ||
>>> polygon1 = Polygon([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]]) | ||
>>> polygon2 = Polygon([[1.5, 1.5], [2.5, 1.5], [2.5, 2.5], [1.5, 2.5]]) | ||
>>> is_intersection_polygon_polygon_xy(polygon1, polygon2) | ||
False | ||
""" | ||
for i in range(len(polygon1)): | ||
line1 = [polygon1[i], polygon1[i - 1]] | ||
for j in range(len(polygon2)): | ||
line2 = [polygon2[j], polygon2[j - 1]] | ||
if is_intersection_segment_segment_xy(line1, line2): | ||
return True | ||
return False | ||
|
||
|
||
def is_intersection_line_line_xy(l1, l2, tol=1e-6): | ||
"""Verifies if two lines intersect on the XY-plane. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking at this code now, would it not be much simpler (and more readable) to do the following:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(see #1130 )