好吧,我們將再次嘗試這個......
考慮了兩下,由通過在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) –