From 7be61bda794a66fb385c3428486c70971ee57ea1 Mon Sep 17 00:00:00 2001 From: ZHANG YU <182837830+xixihaha-ha@users.noreply.github.com> Date: Tue, 3 Nov 2026 11:38:34 +0800 Subject: [PATCH] Include line moment when constructing a plane from a line and point --- spatialmath/geom3d.py | 2 +- tests/test_plane_line_point.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) mode change 100755 => 100644 spatialmath/geom3d.py create mode 100644 tests/test_plane_line_point.py diff --git a/spatialmath/geom3d.py b/spatialmath/geom3d.py old mode 100755 new mode 100644 index 84813a41..4b6c9bc4 --- a/spatialmath/geom3d.py +++ b/spatialmath/geom3d.py @@ -95,7 +95,7 @@ def LinePoint(cls, l: Line3, p: ArrayLike3) -> Self: :seealso: :meth:`PointNormal` :meth:`ThreePoints` """ - n = np.cross(l.w, p) + n = np.cross(l.w, p) - l.v d = np.dot(l.v, p) return cls(np.r_[n, d]) diff --git a/tests/test_plane_line_point.py b/tests/test_plane_line_point.py new file mode 100644 index 00000000..ef880491 --- /dev/null +++ b/tests/test_plane_line_point.py @@ -0,0 +1,26 @@ +import numpy as np +import pytest + +from spatialmath import Line3, Plane3 + + +@pytest.mark.parametrize( + "anchor,direction,point", + [ + ([1, 2, 3], [1, 0, 0], [1, 4, 3]), + ([2, -1, 4], [1, 2, -1], [3, 2, 5]), + ([0, 0, 0], [0, 0, 1], [2, 3, 4]), + ], +) +@pytest.mark.parametrize("scale", [1, -2, 0.25]) +def test_line_point_plane_contains_translated_line(anchor, direction, point, scale): + anchor = np.asarray(anchor, dtype=float) + direction = np.asarray(direction, dtype=float) * scale + line = Line3.PointDir(anchor, direction) + plane = Plane3.LinePoint(line, np.asarray(point, dtype=float)) + + # Use the plane equation directly, independent of Plane3.contains. + for p in [point, anchor, anchor + direction, anchor - 3 * direction]: + np.testing.assert_allclose(plane.n @ p + plane.d, 0, atol=1e-12) + expected_normal = np.cross(direction, np.asarray(point) - anchor) + np.testing.assert_allclose(plane.n, expected_normal, atol=1e-12)