more s-bend fixes and add docs

This commit is contained in:
jan 2026-03-08 22:02:07 -07:00
commit 41a2d9f058
10 changed files with 249 additions and 116 deletions

View file

@ -50,19 +50,43 @@ def test_sbend_generation() -> None:
result = SBend.generate(start, offset, radius, width)
assert result.end_port.y == 5.0
assert result.end_port.orientation == 0.0
assert len(result.geometry) == 2
assert len(result.geometry) == 1 # Now uses unary_union
# Verify failure for large offset
with pytest.raises(ValueError, match=r"SBend offset .* must be less than 2\*radius"):
SBend.generate(start, 25.0, 10.0, 2.0)
def test_bend_snapping() -> None:
# Radius that results in non-integer coords
radius = 10.1234
def test_bend_collision_models() -> None:
start = Port(0, 0, 0)
result = Bend90.generate(start, radius, width=2.0, direction="CCW")
radius = 10.0
width = 2.0
# Target x is 10.1234, should snap to 10.0 (assuming 1.0um grid)
assert result.end_port.x == 10.0
assert result.end_port.y == 10.0
# 1. BBox model
res_bbox = Bend90.generate(start, radius, width, direction="CCW", collision_type="bbox")
# Arc CCW R=10 from (0,0,0) ends at (10,10,90).
# Waveguide width is 2.0, so bbox will be slightly larger than (0,0,10,10)
minx, miny, maxx, maxy = res_bbox.geometry[0].bounds
assert minx <= 0.0 + 1e-6
assert maxx >= 10.0 - 1e-6
assert miny <= 0.0 + 1e-6
assert maxy >= 10.0 - 1e-6
# 2. Clipped BBox model
res_clipped = Bend90.generate(start, radius, width, direction="CCW", collision_type="clipped_bbox", clip_margin=1.0)
# Area should be less than full bbox
assert res_clipped.geometry[0].area < res_bbox.geometry[0].area
def test_sbend_collision_models() -> None:
start = Port(0, 0, 0)
offset = 5.0
radius = 10.0
width = 2.0
res_bbox = SBend.generate(start, offset, radius, width, collision_type="bbox")
# Geometry should be a single bounding box polygon
assert len(res_bbox.geometry) == 1
res_arc = SBend.generate(start, offset, radius, width, collision_type="arc")
assert res_bbox.geometry[0].area > res_arc.geometry[0].area

View file

@ -30,9 +30,9 @@ def test_astar_sbend(basic_evaluator: CostEvaluator) -> None:
# Check if any component in the path is an SBend
found_sbend = False
for res in path:
# Check if it has 2 polygons (characteristic of our SBend implementation)
# and end port orientation is same as start
if len(res.geometry) == 2:
# Check if the end port orientation is same as start
# and it's not a single straight (which would have y=0)
if abs(res.end_port.y - start.y) > 0.1 and abs(res.end_port.orientation - start.orientation) < 0.1:
found_sbend = True
break
assert found_sbend
@ -50,11 +50,6 @@ def test_pathfinder_negotiated_congestion_resolution(basic_evaluator: CostEvalua
net_widths = {"net1": 2.0, "net2": 2.0}
# Force them into a narrow corridor that only fits ONE.
# Obstacles creating a wide wall with a narrow 2um gap at y=5.
# Gap y: 4 to 6. Center y=5.
# Net 1 (y=0) and Net 2 (y=10) both want to go to y=5 to pass.
# But only ONE fits at y=5.
obs_top = Polygon([(20, 6), (30, 6), (30, 15), (20, 10)]) # Lower wall
obs_bottom = Polygon([(20, 4), (30, 4), (30, -15), (20, -10)])