Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
[sympy] Intersections and reflections of rays with jar segments solution in 3rd party category for Escape by Phil15
from sympy import Ray2D, Segment2D
def escape(jar, fly) -> bool:
"""Will the fly escape from the jar before getting tired?"""
(W, H, d), (x0, y0, vx, vy) = jar, fly
jar_corners = (0, H), (0, 0), (W, 0), (W, H)
if (x0, y0) in jar_corners:
# Starting from a corner, make sure direction is right.
i = jar_corners.index((x0, y0))
dx, dy = ((1, -1), (1, 1), (-1, 1), (-1, -1))[i]
vx, vy = dx * abs(vx), dy * abs(vy)
# 0 -- * * -- 3
# | | To visualize directions from corners.
# | | And jar path order.
# 1 -------------- 2
jar_path = ((W - d)/2, H), *jar_corners, ((W + d)/2, H)
jar_segments = list(map(Segment2D, jar_path, jar_path[1:]))
ray = Ray2D((x0, y0), (x0 + vx, y0 + vy))
for nb in range(1, 21):
intersected = []
for segment in jar_segments:
pts = ray.intersect(segment)
if isinstance(pts, Segment2D):
print('No way out along an edge, the fly is in a LOOP...')
return False
try:
# NOTE: pt is necessary the same if defined twice.
pt, = set(pts) - {ray.source}
except ValueError:
continue
intersected.append(segment)
if not intersected:
print(f'The fly is OUT of the jar at step {nb}.')
return True
# The ray is reflected by the only segment it intersects OR GO BACK.
ray = (Ray2D(pt, pt + ray.reflect(intersected[0]).direction)
if len(intersected) == 1 else Ray2D(pt, pt - ray.direction))
print('The fly is TIRED.')
return False
April 5, 2020
Comments: