From be11948a44ddd60c1f15869335520c6183dc3824 Mon Sep 17 00:00:00 2001 From: Eugene Mikhantyev Date: Sun, 15 Mar 2026 14:37:35 +0000 Subject: [PATCH] fix: negate y-axis in graphics transform for correct symbol bounding boxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Library symbols use y-up coordinates while schematics use y-down. The _transform_local_point function was not negating y, causing asymmetric symbols (e.g. power:VEE) to have their bounding boxes computed in the wrong direction — missing overlaps with adjacent components. Co-Authored-By: Claude Opus 4.6 --- python/commands/schematic_analysis.py | 6 +++++- python/tests/test_schematic_analysis.py | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/python/commands/schematic_analysis.py b/python/commands/schematic_analysis.py index 7eab32b..487db15 100644 --- a/python/commands/schematic_analysis.py +++ b/python/commands/schematic_analysis.py @@ -332,8 +332,12 @@ def _transform_local_point( ) -> Tuple[float, float]: """ Transform a point from local symbol coordinates to absolute schematic - coordinates using KiCad's transform order: mirror → rotate → translate. + coordinates using KiCad's transform order: + negate-y (lib y-up → schematic y-down) → mirror → rotate → translate. """ + # Library symbols use y-up; schematic uses y-down + ly = -ly + # Apply mirroring in local coords if mirror_x: ly = -ly diff --git a/python/tests/test_schematic_analysis.py b/python/tests/test_schematic_analysis.py index b287f07..c7c4bcd 100644 --- a/python/tests/test_schematic_analysis.py +++ b/python/tests/test_schematic_analysis.py @@ -749,21 +749,24 @@ class TestTransformLocalPoint: """Test local→absolute coordinate transform.""" def test_no_transform(self): + # ly is negated (lib y-up → schematic y-down) x, y = _transform_local_point(1.0, 2.0, 100.0, 200.0, 0, False, False) assert x == pytest.approx(101.0) - assert y == pytest.approx(202.0) + assert y == pytest.approx(198.0) def test_mirror_x(self): + # y-negate then mirror_x cancel out → net ly unchanged x, y = _transform_local_point(1.0, 2.0, 0.0, 0.0, 0, True, False) assert x == pytest.approx(1.0) - assert y == pytest.approx(-2.0) + assert y == pytest.approx(2.0) def test_mirror_y(self): x, y = _transform_local_point(1.0, 2.0, 0.0, 0.0, 0, False, True) assert x == pytest.approx(-1.0) - assert y == pytest.approx(2.0) + assert y == pytest.approx(-2.0) def test_rotation_90(self): + # ly=0 negated is still 0, then rotate lx=1 by 90° x, y = _transform_local_point(1.0, 0.0, 0.0, 0.0, 90, False, False) assert x == pytest.approx(0.0, abs=1e-9) assert y == pytest.approx(1.0, abs=1e-9)