This commit is contained in:
Jan Petykiewicz 2026-03-09 20:37:03 -07:00
commit 8bf0ff279f
5 changed files with 191 additions and 117 deletions

View file

@ -178,26 +178,28 @@ class CollisionEngine:
for obj_id in candidates:
if self.static_prepared[obj_id].intersects(geometry):
if start_port or end_port:
# Safety zone check: requires intersection of DILATED query and RAW obstacle.
# Always re-buffer here because static check needs full clearance dilation,
# whereas the provided dilated_geometry is usually clearance/2.
dilation = self.clearance
test_poly = geometry.buffer(dilation)
# Optimization: Instead of expensive buffer + intersection,
# use distance() and check if it's within clearance only near ports.
raw_obstacle = self.static_geometries[obj_id]
# If the intersection is within clearance, distance will be < clearance.
# We already know it intersects the dilated obstacle, so distance < clearance.
intersection = test_poly.intersection(self.static_geometries[obj_id])
if intersection.is_empty:
continue
ix_minx, ix_miny, ix_maxx, ix_maxy = intersection.bounds
is_safe = False
for p in [start_port, end_port]:
if p and (abs(ix_minx - p.x) < self.safety_zone_radius and
abs(ix_maxx - p.x) < self.safety_zone_radius and
abs(ix_miny - p.y) < self.safety_zone_radius and
abs(ix_maxy - p.y) < self.safety_zone_radius):
is_safe = True
break
sz = self.safety_zone_radius
# Use intersection bounds to check proximity to ports
# We need the intersection of the geometry and the RAW obstacle
intersection = geometry.intersection(raw_obstacle)
if not intersection.is_empty:
ix_minx, ix_miny, ix_maxx, ix_maxy = intersection.bounds
for p in [start_port, end_port]:
if p and (abs(ix_minx - p.x) < sz and
abs(ix_maxx - p.x) < sz and
abs(ix_miny - p.y) < sz and
abs(ix_maxy - p.y) < sz):
is_safe = True
break
if is_safe:
continue
return True