普通多边形之间的相交测试是个复杂的问题,我们只考虑 轴对齐的 菱形问题即菱形的对角线和坐标轴平行的相交问题。
和坐标轴平行的矩形的相交问题:
矩形A B由左上角定点和右下角定点描述, x轴正方向右, y正方向 向下。
图1
设:A的左上定点 x0y0, 右下 x1 y1 B 左上 x2 y2 右下 x3 y3
二维问题一般降维度处理:
有 如果两个矩形 在 x轴y轴投影都相交, 则两个矩形相交
即: x0 < x3 && x2 < x1 && y0 < y3 && y2 < y1
因为两个坐标轴上的相交区域唯一确定一个 矩形
具体的矩形 范围受 坐标的实际大小关系确定
现在我们需要考虑菱形的问题:
菱形的轴是倾斜的, 那么如何求轴上的投影范围, 来进行相交测试呢?
图2
好吧,这样计算的确有些困难, 我们参见图1, 可以有个思路, 首先确定一个菱形的包围盒, 任意一个菱形都有唯一的轴对称包围盒。
设一个菱形的坐标轴x方向宽度 2* sizeX, 坐标轴y方向 2* sizeY
考虑:以下三种情况
我们需要求得这些菱形组合的包围盒的大小:
设从左上到右下的为菱形的 轴x方向, 从 右上到坐下 为 菱形轴y方向, sx 为x向 菱形的个数, sy 为y方向个数
情况1:
除了第一个菱形块之外, 其它菱形块每增加一个宽度增加一个sizeX 高度增加 一个 sizeY
宽度 = (2+sy-1)*sizeX (sizeX是单个菱形宽度的一半)
高度=(2+sy-1)*sizeY (sizeY 是单个菱形高度的一半)
情况2:(最下面的那个)
宽度 = (2+sx-1)*sizeX
高度=(2+sx-1) *sizeY
最后的复杂情况:
先考虑 沿x 方向的 值, 再加上 y方向的值
宽度 = (2+sx-1 + sy-1)*sizeX
高度 = (2+sx-1 + sy-1)*sizeY
实际上简化之后:
宽度 = (sx+sy)*sizeX
高度 = (sx+sy)*sizeY
这些拼接图形的中点 , 就是他们 包围盒的中点?
可以做上辅助线。 我们根据平线线的分割原理就可以证明
下一个问题是求得这个拼接图形的四个定点的位置; 首先我们需要假定 坐标轴的 0,0点在包围盒的左上角, x向右 ,y向下
上图就是四个顶点的所在位置的值。
最后如何判定相交?
考虑倾斜的轴构成的坐标系:
求一个点在这两个轴上的投影长度 , 可以采用内积:
x轴向: (sizeX, sizeY)
y轴向:(-sizeX, sizeY)
t1 = (x, y) *(sizeX, sizeY)/ ( |(x, y)|)
t2 = (x, y)*(-sizeX, sizeY) /|(x, y)|
所以向判断 矩形一样判断 t1 t2的范围就可以了
下面是pyhon代码:
错了:
不能通过 求内积来求 点在菱形边上的投影, 只有当菱形的边互相垂直的时候才成立;
这是因为 非直角 不是 普通的几何。
那么该怎么办呢? 如何计算相交?
这个我 再想想
如果我们约束 所有的菱形拼图都是 n*n的话, 存在一种解法:
可以计算两个拼图中心的 x y 差值
再根据 拼图的 边的宽度 = sx*sizeX, sx*sizeY
只要保证两个拼图的 x , y 差值 不 小于 边的宽度 就可以了
拼图中心相差的 x y 方向的格子数目, abs(difx)+abs(dify) >= boundA + boundB 则不相交