DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

SymPy 求平行线段到平面距离,报交点解包 ValueError

SymPy 1.14.0 对平面外的平行线段或射线按单个交点解包。已证明平行时可用端点距离,非平行与符号未定输入不能套用,也不能把原对象换成无限直线。

Plane.distance(segment) 处理一条位于平面外的平行线段时,抛出 ValueError: not enough values to unpack (expected 1, got 0)。射线也可能落入同一分支。先看支持直线是否与平面平行,不能把“没有交点”误当成“没有距离”。

当前正式 SymPy 1.14.0 中,线段和射线分支会求支持直线与平面的交点,并按单个结果解包。支持直线在平面外且与之平行时,交集为空,于是解包失败。相交、共面和符号条件未定的输入,需要另外判断。

已经确认平行时,可以计算任一端点到平面的距离

平行意味着沿线段或射线方向移动,不改变沿平面法向量的投影,因此各点到平面的距离相同。下面只处理精确坐标、已证明平行的一条线段:

from sympy import Plane, Point3D, Segment3D

plane = Plane((0, 0, 0), normal_vector=(0, 0, 1))
segment = Segment3D((0, 0, 1), (1, 0, 1))
normal = Point3D(plane.normal_vector)
direction = segment.p2 - segment.p1
if normal.dot(direction).is_zero is not True:
    raise ValueError("this path requires proven parallelism")

distance = plane.distance(segment.p1)
assert distance == 1

这里没有修改线段或平面的几何定义,也没有把一次解包异常统一改成距离 0。同样的端点办法可用于方向已确认平行的射线;它依赖这一几何前提,不能用来替代所有 Plane.distance() 调用。

符号表达式的零判断可能无法确定,示例会拒绝继续,而不是把“不能证明非零”当成“已经平行”。浮点坐标还需要业务认可的误差判据与数值方法,不能随意选一个容差,让真正相交的对象被归为平行。

延长线与线段、射线不是同一个对象

非平行时,支持直线可能与平面相交,但交点在原线段之外,或位于射线的反方向。直接换成 plane.distance(Line3D(...)) 会丢掉这些范围限制,可能错误地得到 0。

对一般输入,应保留线段端点或射线方向,使用经过核对的对应几何处理;不要把内部单元素解包改成“空列表就返回 0”。当前正式版本仍有上述分支,后续采用新版本时需检查实际发行实现,不能以开发阶段的公式或计划代替正式修复。

验收覆盖平行且分离、共面、确实相交、延长线相交但原对象不相交,以及条件未定的符号输入。保留原精确坐标、几何类型和约束;如果旧流程已经把异常样本记为零距离,应逐项重算,而不只是恢复程序运行。