fix(pid): existing line payloads are read tolerantly and crossings follow arcs, not chords
A foreign or hand-edited ACADMCP_PID payload (from: 'garbage', seq: True) made the next pid_line_draw raise TypeError; payload_port_refs / payload_seq now accept only well-formed values and a reader result never raises. An existing polyline with a bulge was tested as its chord, so a line through the arc reported crossings 0; flatten_bulges (pure, pinned against ezdxf.math's flattening) feeds count_crossings on both engines. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
co-authored by
Claude Opus 5
parent
cfb5d5082c
commit
9cb4bee587
@@ -3,6 +3,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
import pytest
|
||||
|
||||
from engineering.pid.lines import (
|
||||
@@ -176,3 +178,41 @@ def test_route_refuses_non_axis_port_directions_with_a_value_error():
|
||||
# Equivalent angles and engine float drift still resolve to the axis.
|
||||
assert route((0, 0), -360.0, (50, 0), 540.0) == [(0.0, 0.0), (50.0, 0.0)]
|
||||
assert route((0, 0), 1e-9, (50, 0), 180.0 - 1e-9) == [(0.0, 0.0), (50.0, 0.0)]
|
||||
|
||||
|
||||
# ── Track A hardening (track E wave 0, Task 7): bulge flattening ─────────────
|
||||
|
||||
|
||||
@pytest.mark.parametrize("bulge", [1.0, -1.0, 0.5, -0.3, 2.0, 0.2])
|
||||
def test_flatten_bulges_matches_ezdxf_flattening(bulge):
|
||||
"""Pinned against ezdxf's own arc flattening: same vertex count, same points."""
|
||||
from ezdxf.math import ConstructionArc, Vec2, bulge_to_arc
|
||||
|
||||
from engineering.pid.lines import FLATTEN_SAGITTA, flatten_bulges
|
||||
|
||||
a, b = (0.0, 0.0), (10.0, 0.0)
|
||||
mine = flatten_bulges([a, b], [bulge])
|
||||
centre, start_rad, end_rad, radius = bulge_to_arc(Vec2(a), Vec2(b), bulge)
|
||||
arc = ConstructionArc(
|
||||
center=centre,
|
||||
radius=radius,
|
||||
start_angle=math.degrees(start_rad),
|
||||
end_angle=math.degrees(end_rad),
|
||||
)
|
||||
reference = [(p.x, p.y) for p in arc.flattening(FLATTEN_SAGITTA)]
|
||||
assert len(mine) == len(reference)
|
||||
assert mine[0] == a and mine[-1] == b
|
||||
assert all(math.hypot(p[0] - centre.x, p[1] - centre.y) == pytest.approx(radius) for p in mine)
|
||||
assert mine[len(mine) // 2] == pytest.approx(reference[len(reference) // 2])
|
||||
|
||||
|
||||
def test_flatten_bulges_passes_straight_edges_through_and_pads_short_bulge_lists():
|
||||
from engineering.pid.lines import flatten_bulges
|
||||
|
||||
pts = [(0.0, 0.0), (10.0, 0.0), (10.0, 10.0)]
|
||||
assert flatten_bulges(pts, []) == pts
|
||||
assert flatten_bulges(pts, [0.0, 0.0, 0.0]) == pts
|
||||
flat = flatten_bulges(pts, [0.0, 1.0])
|
||||
assert flat[0] == (0.0, 0.0) and flat[1] == (10.0, 0.0) and flat[-1] == (10.0, 10.0)
|
||||
assert len(flat) > 3, "the second edge became a semicircle of chords"
|
||||
assert flatten_bulges([(1.0, 1.0)], [1.0]) == [(1.0, 1.0)]
|
||||
|
||||
Reference in New Issue
Block a user