跳转至内容

27. Minkowsky,扩张,相交

周一,手写研究。

Minkowski 差

lua
local function rect_getDiff(x1,y1,w1,h1, x2,y2,w2,h2)
    return x2 - x1 - w1,
           y2 - y1 - h1,
           w1 + w2,
           h1 + h2
end

A 什么时候会撞到 B?转换一下:

A 的某个参考点,一旦走进哪片区域,就代表 A 已经碰到 B?这个区域,就是 Minkowski 差得到的那个矩形。

把“整个 A”压缩成一个点去看,同时把 B 周围扩出一片“只要这个点进来就算撞”的区域,可以叫做“危险区”。

看一维,比如两个线段
A: [x1, x1+4]
B: [x2, x2+5]

A 的右边碰到 B 的左边时,开始接触
A 的左边碰到 B 的右边时,结束接触
只要 A 的位置落在这两个边界之间,就算“重叠/接触”

只盯着 A 的左边那个参考点,为了让这个点也能表达“整个 A 的碰撞”,就必须把 B 扩大一点
A 明明还占 4 的长度,这部分不能凭空消失,所以只能“补到 B 身上”
“危险区”总长度就变成:4+5=9,也就是 w1+w2

再具体一点,x2=13,B 就在 [13, 18]
开始接触,A 的右边碰到 B 的左边,x1+4=13,x1=9
结束接触,A 的左边碰的 B 的右边,x1=18

所以只要 x1 在 [9, 18] 之间,A 和 B 就会重叠/接触,区间长度正好是 18-9=4+5
这就是“扩张”的本质:不是 B 真变大了,而是“允许 A 的参考点进入的危险位置范围”变大了

具体值去掉,现在有 (x1, w1, x2, w2),危险区就是 [x2-w1, x2+w2]

扩展到二维,我们看的不是世界坐标里的危险区,而是相对于 A 的当前位置
需要把 A 平移到原点,危险区左边界就变成了 x2-w1-x1,危险区宽度 w1+w2
横竖都来一遍就会返回一个危险矩形,也就是上面函数返回的内容