freeroute/tests/geometry/test_polyline.py
Ryan Malloy 2d394872e3 Add Polyline/PolylineShape: the swept copper of a trace
Ports the trace-relevant subset of geometry/planar/{Polyline,PolylineShape,
LineSegment}: a Polyline is a trace centreline (integer corners); a
PolylineShape is that centreline swept by the half-width, returned as exact
convex IntBox tiles (one flush box per orthogonal segment plus a square at
each interior corner to cover the turn). Exact for orthogonal segments; a
conservative bounding box for a diagonal one (never under-reports an
overlap). 45-degree/IntOctagon caps are deferred.
2026-07-13 02:16:02 -06:00

45 lines
1.5 KiB
Python

"""Tests for Polyline / PolylineShape (the swept trace copper)."""
from __future__ import annotations
from freeroute.geometry import IntBox, IntPoint, Polyline, PolylineShape, segment_box
def test_polyline_segments():
pl = Polyline([IntPoint(0, 0), IntPoint(10, 0), IntPoint(10, 10)])
segs = list(pl.segments())
assert len(segs) == 2
assert pl.corner_count() == 3
assert not pl.is_empty()
assert Polyline([IntPoint(0, 0)]).is_empty()
def test_segment_box_horizontal_is_flush_in_x():
box = segment_box(IntPoint(0, 0), IntPoint(100, 0), 10)
# flush in the travel direction (x), offset by half-width in y
assert box == IntBox(0, -10, 100, 10)
def test_segment_box_vertical_is_flush_in_y():
box = segment_box(IntPoint(0, 0), IntPoint(0, 100), 10)
assert box == IntBox(-10, 0, 10, 100)
def test_polyline_shape_tiles_include_corner_squares():
pl = Polyline([IntPoint(0, 0), IntPoint(100, 0), IntPoint(100, 100)])
tiles = PolylineShape(pl, 10).tiles()
# 2 segment boxes + 1 interior-corner square
assert len(tiles) == 3
# the corner square is centred on the turn at (100, 0)
assert IntBox(90, -10, 110, 10) in tiles
def test_polyline_shape_bounding_box():
pl = Polyline([IntPoint(0, 0), IntPoint(100, 0)])
assert PolylineShape(pl, 5).bounding_box() == IntBox(-5, -5, 105, 5)
def test_diagonal_segment_box_is_conservative_bbox():
box = segment_box(IntPoint(0, 0), IntPoint(50, 50), 10)
assert box == IntBox(-10, -10, 60, 60)