Skip to content

Commit 3051413

Browse files
akapkotelakapkotel
and
akapkotel
authored
Merge remote-tracking branch 'upstream/development' into using_shapely_to_find_line_of_sight (#788)
1. Replaced all geometry collision test with shapely functions. 2. Replaced math.sqrt function with math.hypot in get_distance function because hypot is faster - see math module documentation. 3. Removed some redundant local assignments in sprite_list.py functions with straightforward returns. Co-authored-by: akapkotel <[email protected]>
1 parent 9844fba commit 3051413

File tree

2 files changed

+16
-62
lines changed

2 files changed

+16
-62
lines changed

arcade/geometry.py

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
"""
22
Functions for calculating geometry.
33
"""
4+
from shapely import speedups
5+
from shapely.geometry import LineString, Polygon, Point
46

57
from typing import cast
68
from arcade import PointList
79
import math
810

911
_PRECISION = 2
1012

13+
speedups.enable()
14+
1115

1216
def are_polygons_intersecting(poly_a: PointList,
1317
poly_b: PointList) -> bool:
@@ -21,38 +25,10 @@ def are_polygons_intersecting(poly_a: PointList,
2125
:rtype bool:
2226
"""
2327

24-
for polygon in (poly_a, poly_b):
25-
26-
for i1 in range(len(polygon)):
27-
i2 = (i1 + 1) % len(polygon)
28-
projection_1 = polygon[i1]
29-
projection_2 = polygon[i2]
30-
31-
normal = (projection_2[1] - projection_1[1],
32-
projection_1[0] - projection_2[0])
33-
34-
min_a, max_a, min_b, max_b = (None,) * 4
35-
36-
for poly in poly_a:
37-
projected = normal[0] * poly[0] + normal[1] * poly[1]
28+
shapely_polygon_a = Polygon(poly_a)
29+
shapely_polygon_b = Polygon(poly_b)
3830

39-
if min_a is None or projected < min_a:
40-
min_a = projected
41-
if max_a is None or projected > max_a:
42-
max_a = projected
43-
44-
for poly in poly_b:
45-
projected = normal[0] * poly[0] + normal[1] * poly[1]
46-
47-
if min_b is None or projected < min_b:
48-
min_b = projected
49-
if max_b is None or projected > max_b:
50-
max_b = projected
51-
52-
if cast(float, max_a) <= cast(float, min_b) or cast(float, max_b) <= cast(float, min_a):
53-
return False
54-
55-
return True
31+
return shapely_polygon_a.intersects(shapely_polygon_b)
5632

5733

5834
def is_point_in_polygon(x, y, polygon_point_list):
@@ -67,27 +43,12 @@ def is_point_in_polygon(x, y, polygon_point_list):
6743
Returns: bool
6844
6945
"""
70-
n = len(polygon_point_list)
71-
inside = False
72-
if n == 0:
73-
return False
74-
75-
p1x, p1y = polygon_point_list[0]
76-
for i in range(n+1):
77-
p2x, p2y = polygon_point_list[i % n]
78-
if y > min(p1y, p2y):
79-
if y <= max(p1y, p2y):
80-
if x <= max(p1x, p2x):
81-
if p1y != p2y:
82-
xints = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
83-
# noinspection PyUnboundLocalVariable
84-
if p1x == p2x or x <= xints:
85-
inside = not inside
86-
p1x, p1y = p2x, p2y
87-
88-
return inside
46+
shapely_point = Point(x, y)
47+
shapely_polygon = Polygon(polygon_point_list)
48+
49+
return shapely_polygon.contains(shapely_point)
8950

9051

9152
def get_distance(x1: float, y1: float, x2: float, y2: float):
9253
""" Get the distance between two points. """
93-
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
54+
return math.hypot(x1 - x2, y1 - y2)

arcade/sprite_list.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ def check_for_collision_with_list(sprite: Sprite,
11681168
sprite_list_to_check = sprite_list
11691169

11701170
# print(len(sprite_list_to_check.sprite_list))
1171-
collision_list = [sprite2
1171+
return [sprite2
11721172
for sprite2 in sprite_list_to_check
11731173
if sprite is not sprite2 and _check_for_collision(sprite, sprite2)]
11741174

@@ -1177,7 +1177,6 @@ def check_for_collision_with_list(sprite: Sprite,
11771177
# if sprite1 is not sprite2 and sprite2 not in collision_list:
11781178
# if _check_for_collision(sprite1, sprite2):
11791179
# collision_list.append(sprite2)
1180-
return collision_list
11811180

11821181

11831182
def get_sprites_at_point(point: Point,
@@ -1200,11 +1199,9 @@ def get_sprites_at_point(point: Point,
12001199
else:
12011200
sprite_list_to_check = sprite_list
12021201

1203-
collision_list = [sprite2
1204-
for sprite2 in sprite_list_to_check
1205-
if is_point_in_polygon(point[0], point[1], sprite2.get_adjusted_hit_box())]
1202+
return [s for s in sprite_list_to_check if
1203+
is_point_in_polygon(point[0], point[1], s.get_adjusted_hit_box())]
12061204

1207-
return collision_list
12081205

12091206
def get_sprites_at_exact_point(point: Point,
12101207
sprite_list: SpriteList) -> List[Sprite]:
@@ -1226,8 +1223,4 @@ def get_sprites_at_exact_point(point: Point,
12261223
else:
12271224
sprite_list_to_check = sprite_list
12281225

1229-
collision_list = [sprite2
1230-
for sprite2 in sprite_list_to_check
1231-
if point[0] == sprite2.center_x and point[1] == sprite2.center_y]
1232-
1233-
return collision_list
1226+
return [s for s in sprite_list_to_check if s.position == point]

0 commit comments

Comments
 (0)