这句话听着像废话。它不是。
welded_bracket 这件夹具,我们把它的面列表打乱 12 次重新解析,得到了 3 种 不同的毛坯:85.97×60.97 两片、60.97×55 三片、60.97×55 四片。三个答案里最多 只有一个是对的,而它们出自同一份几何、同一份代码。
一条漏掉的物理约束
根因在面板配对上。一块钣金面板有两张皮,它们都是材料外向的法向,因此必然 反向。判据里漏了这一条,那个"带符号"的检验就变得不对称:
(w, v) 通过 而 (v, w) 不通过于是候选集合取决于谁先被枚举到。而 STEP 文件重新导出一次,面序常常就变了—— 这不是理论风险,是真实使用中随时会踩到的东西。客户把同一个模型另存一遍发过来, 毛坯就换了个数。
补上"外向法向必须反向"这条零阈值的物理约束之后:16 个夹具 × 12 次乱序, 0 次不一致;welded_bracket 收敛到唯一且物理正确的答案(85.97×60.97 = corner_bracket 的毛坯 + 对接板 = 2 片),体积恒等式从 0.9849 回到 1.0000。
值得注意的是修法:不是加一条排序把顺序钉死,而是补上一条本来就成立的物理 事实。钉死顺序只能掩盖症状——判据依然是不对称的,换个触发条件还会漏出来。
不变量比用例更能发现问题
这件事之后我们加了一套鲁棒性门禁,判的全是不变量:同一个零件换个"写法", 结论必须不变。破了,就说明算法依赖了某个偶然条件。
- 面序无关:墙面列表乱序 12 次,配对结果必须一致;
- 位置无关:把件摆到离原点 10⁵ mm,板厚 / 折弯数 / 毛坯不变;
- 镜像对称:左右件结论相同;
- 缩放协变:支持区间内(0.25×–5×)等比缩放,结果等比;
- 越界拒答:0.1× / 10× 落到板厚区间外时判
not_sheet并给通用几何事实, 不猜一个数往下算。
这类测试有一个好处:它不需要标准答案。我们不必事先知道这件的毛坯该是多少, 只需要知道"不管怎么打乱,答案得是同一个"。而标准答案往往正是最难拿到的东西。
编号也是同一件事
零件上的特征编号(B 折弯、H 孔、C 切割轮廓)也不能按检出顺序编——那会随实现 细节漂移。我们改成沿零件最长边从一头数到另一头,跟人拿着图纸从左往右点数 是同一个顺序。
同一份文件反复解析,号一模一样。这是编号唯一的用处所在:车间拿着 H3 去对图纸, 如果昨天的 H3 和今天的 H3 不是同一个孔,这套编号就是负资产。