好吧,我们将再次尝试这个......
考虑了两下,由通过在ABCD从每一个顶点画一条线(黑色)到EFGH(红色)定义区域的联合:
这里最难的是未来与所有这些线定义的形状
一旦你(无论是灰色系和原线从ABCD和EFGH矩形来了。)图出来,创建一个链接l并且假设这些形状中的每一个存在于交叉点内。
第1步。翻译&旋转一切,以便ABCD在0,0上有一个顶点,它的线与x和y轴平行/垂直。
步骤1A。在ABCD中查找最低的y值顶点,然后从场景中的所有其他顶点中减去它。我们假设为了演示目的,该顶点是C.通过从场景中的每个顶点减去C,我们将有效地将原点(0,0)移动到C,使得围绕C的旋转变得容易。
for all shapes in linked list {
for all vertices in shape {
vertex -= C;
}
}
步骤1B。绕着由等于所述C-> B载体和x轴之间的角度的角度的原点一切,所以在x轴即乙土地:
// see http://en.wikipedia.org/wiki/Atan2
float rotRadians = atan2(B.x, B.y); // assuming ABCD vertices are labelled clockwise
for all shapes in linked list {
for all vertices in shape {
rot(thisVert, rotRadians);
}
}
// ...
// function declaration
void rot(theVertex, theta) {
tempX = theVertex.x;
tempY = theVertex.y;
theVertex.x = cos(theta) * tempX + sin(theta) * tempY;
theVertex.y = cos(theta) * tempY - sin(theta) * tempX;
}
如果ABCD顶点被标记顺时针ABCD的顶点,现在应该是这样的:
A = ABCDx , ABCDy
B = ABCDx , 0
C = 0 , 0
D = 0 , ABCDy
(顺时针如果他们没有标签,那么“内在于”为您在第2步是行不通的,所以一定要确保在atan2(...)
调用中使用的是VERT顶点逆时针从最低点开始)。
第2步。现在我们可以很容易地分析一个形状是否位于ABCD矩形内,例如, if (thisVert.x >= 0 && thisVert.y >= 0 && thisVert.x <= ABCDx && thisVert.y <= ABCDy)
。遍历形状的链接列表,并检查以确保每个形状的每个顶点位于ABCD内。如果一个形状的一个顶点不在ABCD内,那么该形状不是ABCD/EFGH交点的一部分。将其标记为不是交叉点的一部分并跳到下一个形状。
第3步。撤消步骤1B的旋转,然后撤消步骤1A的翻译。
第4步。用EFGH而不是ABCD重复步骤1-3,您将拥有交集。
如果两组之间唯一的交集是一条直线,那么上述将不返回任何交集。如果交点== NULL,则检查相交的线。
如果交点仍为NULL,则检查相交点。
许多重复例如[非轴对齐的矩形相交](http://stackoverflow.com/questions/2089173/non-axis-aligned-rectangle-intersection) –