资讯详情

原点在A−B里,就等于两形状相交

📅 2026/10/16 2:12:12 | 华诺云谱 👁 阅读
原点在A−B里,就等于两形状相交
一句话A − B 里的每个点都代表A 上某点到 B 上某点的相对位置。原点 (0,0) 代表相对位置为零也就是两点重合。所以 A − B 包含原点就说明 A 和 B 有重合的点也就是相交。下面用 5 个角度来理解从最简单的开始。一、先澄清A − B 不是挖掉一块很多人卡在第一步是因为把 A − B 理解成从 A 里挖掉 B。不是这个意思。写法含义集合差 A \ B属于 A、但不属于 B 的部分挖掉闵可夫斯基差 A − BA 里每个点减去 B 里每个点得到的所有结果A − B { a − b | a 属于 Ab 属于 B }它是一个全新的形状通常比 A、B 都大位置也不在 A 或 B 原来的地方。二、角度 1一个点就是一个箭头a − b是一个向量表示从 b 指向 a 的箭头。b ●──────────→● a a − b 这根箭头把 A 上任取一点、B 上任取一点都画一根箭头所有可能的箭头的终点从原点画起汇总起来就是 A − B。那么有没有一根箭头长度为 0 ⇔ 有没有 a 和 b 在同一个位置 ⇔ A 和 B 有没有共同的点 ⇔ A 和 B 相不相交而长度为 0 的箭头画出来就是原点。原点在 A − B 里 ⇔ 存在一根零长度箭头 ⇔ A、B 有重合点 ⇔ 相交。这就是整个转化的本质没有任何额外的魔法。三、角度 2一维数轴上最清楚把形状简化成数轴上的线段A [1, 3] B [2, 5]A − B 的范围最小值 A 最小 − B 最大最大值 A 最大 − B 最小A − B [1 − 5, 3 − 2] [-4, 1] ← 包含 0 → 相交 ✅检查一下A、B 在 [2, 3] 区间确实重叠了。再把 B 挪远A [1, 3] B [4, 6] A − B [1 − 6, 3 − 4] [-5, -1] ← 不含 0 → 不相交 ❌而且你会发现原点到区间 [-5, -1] 的距离是 1正好等于 A、B 之间的空隙3 到 4。这不是巧合后面会讲。四、角度 3你早就用过它了圆和圆的碰撞你一定写过boolhitVector2.Distance(ca,cb)rarb;用闵可夫斯基差来看A 是圆圆心 ca半径 ra B 是圆圆心 cb半径 rb A − B 圆心在 (ca − cb)、半径为 (ra rb) 的圆“原点在这个圆里” ⇔ 原点到圆心 (ca − cb) 的距离 ≤ ra rb ⇔|ca − cb| ≤ ra rb。和你熟悉的公式一模一样。包围盒AABB的碰撞boolhitMathf.Abs(ca.x-cb.x)ha.xhb.xMathf.Abs(ca.y-cb.y)ha.yhb.y;// h 是半宽、半高A − B 中心在 (ca − cb)、半宽为 (ha hb) 的矩形 原点在里面 ⇔ 上面那两个不等式成立结论圆碰撞、AABB 碰撞其实都是原点在不在 A − B 里的特例。GJK 只是把这个思路推广到了任意凸形状。五、角度 4把 B 缩成一个点把它的体积加给 A这是最直观的几何画面。想象过程把 B缩成一个点放在原点为了保持公平把 B 原本的胖瘦补到 A 身上——让 A 变胖现在问题变成这个点原点在不在变胖后的 A 里具体怎么变胖A − B A (−B) ① 把 B 绕原点翻转 180°得到 −B ② 让 −B 的中心沿着 A 走一圈扫过的区域就是 A − B以圆碰方块为例方块 A A − B圆角方块 ┌──────┐ ╭──────────╮ │ │ ⟶ │ │ │ │ │ │ └──────┘ ╰──────────╯ 方块每条边向外扩了一个圆的半径这就像机器人走迷宫的经典做法把机器人当成一个点把墙壁向外加厚机器人的半径只要这个点不进入加厚的墙机器人就不会撞墙。六、角度 5移动形状 平移差集如果把 A 移动 Δ(A Δ) − B (A − B) ΔA − B 整体跟着平移 Δ形状完全不变。于是A、B 靠近 ⇔ A − B 朝原点靠近 A、B 碰上 ⇔ A − B 的边缘碰到原点 A、B 嵌入 ⇔ 原点进入 A − B 内部更进一步前面一维例子里的巧合其实是一个普遍规律A、B 的关系在 A − B 中对应两形状之间的最短距离原点到 A − B 的最短距离刚好接触原点在 A − B 的边界上穿透深度和推开方向原点到 A − B边界最近点的距离和方向EPA 求的就是这个所以这个转化不只是能判断撞没撞距离、穿透深度、推开方向都能从这一个形状上读出来。七、为什么值得这样转化原问题两个形状各自有位置、旋转、顶点要比较它们之间的关系 ↓ 新问题一个形状 一个固定的点原点好处问题更简单判断点是否在凸形状里比两个形状是否重叠容易得多原点固定不动搜索方向永远是朝原点算法写起来很统一不用真的构造差集靠支撑函数Support(A, d) − Support(B, −d)随用随取凸 − 凸 还是凸A、B 是凸的A − B 也一定是凸的所以可以用三角形围住原点的方式判断一句话总结A − B 收集了 A 上的点到 B 上的点的所有相对位置。原点代表相对位置为零也就是两点重合。所以原点在 A − B 里 ⇔ 存在重合点 ⇔ 相交原点离 A − B 多远 ⇔ 两形状离多远。你熟悉的距离 ≤ 半径之和圆和各轴区间重叠AABB都是这个原理的特例GJK 只是把它推广到了任意凸形状。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑