分離軸碰撞檢測演算法,sat(separating axis theorem),適用於凸多邊形之間的碰撞檢測。 如果能找到乙個軸,將兩個多邊形分離,則說明兩個多邊形不相交。
傳統的演算法是找到乙個分離軸,得到分離軸的垂線(投影軸),然後將兩個多邊形的所有點都分別投影到該垂線上,如果兩個多邊形的投影區間不重疊,說明不相交。投影軸,需要選擇兩個多邊形的所有邊的垂線。演算法的複雜度為:o((
演算法偽**:
function
sattest
(shape1, shape2)
return
sattesthalf
(shape1, shape2)
andsattesthalf
(shape2, shape1)
endfunction
sattesthalf
(shape1, shape2)
for edge in shape1的所有邊 do
axis = 獲得edge的垂線
range1 = 將 shape1 的所有頂點投影到axis上,得到最大和最小值
range2 = 將 shape2 的所有頂點投影到axis上,得到最大和最小值
if range1 與 range2 無交集 then
return 不相交
endendreturn 相交
end
如果是矩形和多邊形碰撞檢測,對於平行的軸,只用計算一次即可。
我發現一種更簡單的演算法,只需要找到一條軸,能將兩個多邊形的頂點分開即可。分別取兩個多邊形的每乙個邊作為分離軸,先計算出多邊形本身在軸的哪一側(也就是多邊形內側的方向),如果另乙個多邊形的所有點都在該軸的相反側,則兩個多邊形不相交。演算法複雜度為o(m
n)o(mn)
o(mn
)。當然這種演算法要求頂點數量大於等於3,且頂點是順序排列的,也就是所有頂點順序連線起來是目標凸多邊形。
演算法偽**:
function
sattest
(shape1, shape2)
return
sattesthalf
(shape1, shape2)
andsattesthalf
(shape2, shape1)
endfunction
sattesthalf
(shape1, shape2)
side1 = 計算shape1內側的方向
for edge in shape1的所有邊 do
side2 = 獲得shape2所有頂點在edge的那一側
if side1 和 side2 在不同側 then
return 不相交
endendreturn 相交
end
用向量叉乘可以計算乙個向量在另乙個向量的哪一側
int
whitchside
(vector2 a,
vector2 b,
vector2 c)
如果多邊形頂點是順序排列的,只需要前3個頂點,就能計算出多邊形內側的方向。因為做判定取的每一條邊都是用頂點順序連線的,所以內側朝向始終是相等的。
side =
witchside
(shape.vertices[0]
, shape.vertices[1]
, shape.vertices[2]
)
bool
contains
(list
vertices,
vector2 point)
// 先計算出內部的方向
int innerside =
whitchside
(vertices[0]
, vertices[1]
, vertices[2]
);// 通過判斷點是否均在三條邊的內側,來判定單形體是否包含點
for(
int i =
0; i < n;
++i)
}return
true
;}
分離軸演算法的關鍵,就是找到一條軸,能夠將兩個多邊形的頂點分離開。本文demo使用unity3d引擎開發,工程已上傳github: 5 分離測試韌體
我們把測試韌體分離到init.py,類名稱為inittest,如下 import unittest from selenium import webdriver class inittest unittest.testcase defsetup self self.driver webdriver....
2020 2 3 分離整數與小數
我的程式 程式的版權和版本宣告部分 檔名稱 test.c 作 者 容瀟軍 完成日期 2020 年 2 月 3 日 版 本 號 v1.0 對任務及求解方法的描述部分 輸入描述 樣例 123.456 問題描述 編寫乙個程式,其功能為 從鍵盤上輸入乙個浮點數 小數點後有三位數 然後分別輸出該數的整數部分和...
C 1 分離各位數
任務和 檔名稱 main.c 作 者 楊隆勝 完成日期 2017年5月16日 版 本 號 v1.0 問題描述 寫乙個程式,輸入x 三位數 輸出其個 十 百位數,用空格隔開。樣例輸入 768 樣例輸出 8 6 7 輸入描述 輸入x 三位數 程式輸出 輸出其個 十 百位數,用空格隔開 include i...