initial pass on examples
This commit is contained in:
parent
07d079846b
commit
82aaf066e2
19 changed files with 600 additions and 238 deletions
|
|
@ -40,16 +40,9 @@ class CollisionEngine:
|
|||
self.obstacle_geometries[obj_id] = polygon
|
||||
self.prepared_obstacles[obj_id] = prep(polygon)
|
||||
|
||||
# Index the bounding box of the polygon (dilated for broad prune)
|
||||
# Spec: "All user-provided obstacles are pre-dilated by (W_max + C)/2"
|
||||
dilation = (self.max_net_width + self.clearance) / 2.0
|
||||
dilated_bounds = (
|
||||
polygon.bounds[0] - dilation,
|
||||
polygon.bounds[1] - dilation,
|
||||
polygon.bounds[2] + dilation,
|
||||
polygon.bounds[3] + dilation,
|
||||
)
|
||||
self.static_obstacles.insert(obj_id, dilated_bounds)
|
||||
# Index the bounding box of the original polygon
|
||||
# We query with dilated moves, so original bounds are enough
|
||||
self.static_obstacles.insert(obj_id, polygon.bounds)
|
||||
|
||||
def add_path(self, net_id: str, geometry: list[Polygon]) -> None:
|
||||
"""Add a net's routed path to the dynamic R-Tree."""
|
||||
|
|
@ -119,13 +112,13 @@ class CollisionEngine:
|
|||
end_port: Port | None = None,
|
||||
) -> bool:
|
||||
"""Check if a pre-dilated geometry collides with static obstacles."""
|
||||
# Broad prune with R-Tree
|
||||
# Query R-Tree using the bounds of the dilated move
|
||||
candidates = self.static_obstacles.intersection(dilated_geometry.bounds)
|
||||
|
||||
for obj_id in candidates:
|
||||
# Use prepared geometry for fast intersection
|
||||
if self.prepared_obstacles[obj_id].intersects(dilated_geometry):
|
||||
# Check safety zone (2nm = 0.002 um)
|
||||
# Check safety zone (2nm radius)
|
||||
if start_port or end_port:
|
||||
obstacle = self.obstacle_geometries[obj_id]
|
||||
intersection = dilated_geometry.intersection(obstacle)
|
||||
|
|
@ -133,20 +126,23 @@ class CollisionEngine:
|
|||
if intersection.is_empty:
|
||||
continue
|
||||
|
||||
# Create safety zone polygons
|
||||
safety_zones = []
|
||||
# Precise check: is every point in the intersection close to either port?
|
||||
ix_minx, ix_miny, ix_maxx, ix_maxy = intersection.bounds
|
||||
|
||||
is_near_start = False
|
||||
if start_port:
|
||||
safety_zones.append(Point(start_port.x, start_port.y).buffer(0.002))
|
||||
if (abs(ix_minx - start_port.x) < 0.0021 and abs(ix_maxx - start_port.x) < 0.0021 and
|
||||
abs(ix_miny - start_port.y) < 0.0021 and abs(ix_maxy - start_port.y) < 0.0021):
|
||||
is_near_start = True
|
||||
|
||||
is_near_end = False
|
||||
if end_port:
|
||||
safety_zones.append(Point(end_port.x, end_port.y).buffer(0.002))
|
||||
|
||||
if safety_zones:
|
||||
safe_poly = unary_union(safety_zones)
|
||||
# Remove safe zones from intersection
|
||||
remaining_collision = intersection.difference(safe_poly)
|
||||
if remaining_collision.is_empty or remaining_collision.area < 1e-9:
|
||||
continue
|
||||
if (abs(ix_minx - end_port.x) < 0.0021 and abs(ix_maxx - end_port.x) < 0.0021 and
|
||||
abs(ix_miny - end_port.y) < 0.0021 and abs(ix_maxy - end_port.y) < 0.0021):
|
||||
is_near_end = True
|
||||
|
||||
if is_near_start or is_near_end:
|
||||
continue
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue