1 """Optimized collision detection functions."""
4 """Return true if two circles are overlapping.
6 Usually, you'll want to use the 'collides' method instead, but
7 this one can be useful for just checking to see if the player has
8 entered an area or hit a stationary oject.
10 (This function is optimized.)
32 radius_a = getattr3(a, 'radius', 0.5)
33 radius_b = getattr3(b, 'radius', 0.5)
34 radius = radius_a + radius_b
36 return dx * dx + dy * dy <= radius * radius
39 cdef int _collides(float xa, float xb, float ya, float yb,
40 float pxa, float pxb, float pya, float pyb,
41 float radius_a, float radius_b):
43 """Check collision for two moving circles."""
59 radius = radius_a + radius_b
61 # Translate b's final position to be relative to a's start.
62 # And now, circle/line collision.
63 dir_x = pxa + (xb - xa) - pxb
64 dir_y = pya + (yb - ya) - pyb
66 if (dir_x < 0.0001 and dir_x > -0.0001
67 and dir_y < 0.0001 and dir_y > -0.0001):
68 # b did not move relative to a, so do point/circle.
71 return dx * dx + dy * dy < radius * radius
76 # dot(diff, dir) / dot(dir, dir)
77 t = (diff_x * dir_x + diff_y * dir_y) / (dir_x * dir_x + dir_y * dir_y)
83 dist_x = pxa - (pxb + dir_x * t)
84 dist_y = pya - (pyb + dir_y * t)
87 return dist_x * dist_x + dist_y * dist_y <= radius * radius
90 """Return true if the two moving circles collide.
92 a and b should have the following attributes:
94 x, y - required, current position
95 px, py - not required, defaults to x, y, previous frame position
96 radius - not required, defaults to 0.5
98 (This function is optimized.)
119 radius_a = getattr3(a, 'radius', 0.5)
120 radius_b = getattr3(b, 'radius', 0.5)
122 pxa = getattr3(a, 'px', xa)
123 pya = getattr3(a, 'py', ya)
124 pxb = getattr3(b, 'px', xb)
125 pyb = getattr3(b, 'py', yb)
127 return _collides(xa, xb, ya, yb, pxa, pxb, pya, pyb, radius_a, radius_b)
129 def collides_all(a, others):
130 """Filter the second argument to those that collide with the first.
132 This is equivalent to filter(lambda o: collides(a, o), others),
133 but is much faster when the compiled extension is available (which
161 radius_a = getattr3(a, 'radius', 0.5)
162 pxa = getattr3(a, 'px', xa)
163 pya = getattr3(a, 'py', ya)
172 radius_b = getattr3(b, 'radius', 0.5)
173 pxb = getattr3(b, 'px', xb)
174 pyb = getattr3(b, 'py', yb)
176 if _collides(xa, xb, ya, yb, pxa, pxb, pya, pyb, radius_a, radius_b):