判斷點是否在三角形內

最近在公司寫一個把N多邊形分割成N-2個三角形的算法,其中裏面涉及到一個算法是判斷點是否在三角形中的算法,個人也有想到幾種方法,網上也有各種算法,現在就把這個算法進行一個總結記錄給有需要的小夥伴。
1.叉乘法判斷點是否在三角形內
沿着三角形的邊按順時針方向走,判斷該點是否在每條邊的右邊(這可以通過叉乘判斷),如果該點在每條邊的右邊,則在三角形內,否則在三角形外。這個算法只用到了三次叉乘,沒有除法運算和三角函數、開根號等運算,所以效率很高,而且精度很高(沒有浮點誤差)。
設三角形三點A(x1,y1)B(x2,y2)C(x3,y3),已知點M(x,y),
1,先求出三個向量MA,MB,MC.
2,計算MA X MB,MB X MC,MC X MA (X表叉乘)
3,如果此三組的向量叉乘的結果都是同號的(或都正,或都負),即方向相同的,則說明點M在三角形每條邊的同側,即內部。否則必在外部!
具體示例:
A(0,3) B(0,0) C(3,0)

M(1,1)
MA (1,-2)
MB (1,1)
MC (-2,1)

MA X MB = 3
MB X MC = 3
MC X MA = 3

N(3,3)
NA (3,0)
NB (3,3)
NC (0,3)

NA X NB = 9
NB X NC = 9
NC X NA = -9

根據以上規則可判斷M點在內 N點在外


2.設三角形三個點
A(a1,a2),B(b1,b2),C(c1,c2)
三條邊方程
BC:fa(x,y)=0
AC:fb(x,y)=0
AB:fc(x,y)=0
以BC爲例,在三角形內的點必須與點A在BC的同側
所以對於點D(x,y)
在三角形內首先要滿足fa(x,y)*fa(a1,a2)>0
其他邊也同理
所以只要比較
fa(x,y)*fa(a1,a2)
fb(x,y)*fb(b1,b2)
fc(x,y)*fc(c1,c2)
這三個數的正負性,以下是幾種情況
1三個數都是正數:D在三角形內
2至少有一個負數:D在三角形外
3有且只有一個0,另兩個爲正數:在三角形邊上
4有且只有一個0,一個正數一個負數:在三角形邊的延長線上,也算在三角形外,因爲滿足2
5有二個0:在三角形的頂點上

6不可能出現3個0,或3個負數,或一個0兩個負數的情況


3.設三角形爲ABC 所判斷點爲P area表示面積函數
判斷 area(PAB)+area(PAC)+area(PBC)-area(ABC)與0關係
大於0 則在三角形外部

等於0 則在三角形內部


4.設ap×ab 代表矢量ap與ab的矢性積,其座標表達式爲
ap×ab = (xp-xa)*(yb-ya)-(yp-ya)*(xb-xa)
於是判別過程如下:
若 ap×ab>0 and bp×bc>0 and cp×ca>0 或 ap×ab<0 and bp×bc<0 and cp×ca<0
則可判定p在△abc內。

若 ap×ab=0 and (bp×bc>0 and cp×ca>0 或 bp×bc<0 and cp×ca<0)
或 bp×bc=0 and (ap×ab>0 and cp×ca>0 或 ap×ab<0 and cp×ca<0)
或 cp×ca=0 and (ap×ab>0 and bp×bc>0 或 ap×ab<0 and bp×bc<0)
則可判定p在△abc輪廓上。

否則,p在△abc在外。


5.內角和法
連接點P和三角形的三個頂點得到三條線段PA,PB和PC,

求出這三條線段與三角形各邊的夾角,如果所有夾角之和爲360度,那麼點P在三角形內,否則不在


6.同向法
假設點P位於三角形內,會有這樣一個規律,
當我們沿着ABCA的方向在三條邊上行走時,你會發現點P始終位於邊AB,BC和CA的右側。
我們就利用這一點,但是如何判斷一個點在線段的左側還是右側呢?
我們可以從另一個角度來思考,當選定線段AB時,點C位於AB的右側,同理選定BC時,點A位於BC的右側,最後選定CA時,點B位於CA的右側,所以當選擇某一條邊時,我們只需驗證點P與該邊所對的點在同一側即可。

問題又來了,如何判斷兩個點在某條線段的同一側呢?可以通過叉積來實現,連接PA,將PA和AB做叉積,再將CA和AB做叉積,如果兩個叉積的結果方向一致,那麼兩個點在同一測。判斷兩個向量的是否同向可以用點積實現,如果點積大於0,則兩向量夾角是銳角,否則是鈍角。




7.重心法
上面這個方法簡單易懂,速度也快,下面這個方法速度更快,只是稍微多了一點數學而已
三角形的三個點在同一個平面上,如果選中其中一個點,其他兩個點不過是相對該點的位移而已,比如選擇點A作爲起點,那麼點B相當於在AB方向移動一段距離得到,而點C相當於在AC方向移動一段距離得到。


所以對於平面內任意一點,都可以由如下方程來表示:
P = A + u * (C – A) + v * (B - A) // 方程1
如果係數u或v爲負值,那麼相當於朝相反的方向移動,即BA或CA方向。那麼如果想讓P位於三角形ABC內部,u和v必須滿足什麼條件呢?有如下三個條件:
u >= 0
v >= 0
u + v <= 1
幾個邊界情況,當u = 0且v = 0時,就是點A,當u = 0,v = 1時,就是點B,而當u = 1, v = 0時,就是點C。
整理方程1得到P – A = u(C - A) + v(B - A)。
令v0 = C – A, v1 = B – A, v2 = P – A,則v2 = u * v0 + v * v1,現在是一個方程,兩個未知數,無法解出u和v,將等式兩邊分別點乘v0和v1的到兩個等式。
(v2) • v0 = (u * v0 + v * v1) • v0
(v2) • v1 = (u * v0 + v * v1) • v1
注意到這裏u和v是數,而v0,v1和v2是向量,所以可以將點積展開得到下面的式子。
v2 • v0 = u * (v0 • v0) + v * (v1 • v0)  // 式1
v2 • v1 = u * (v0 • v1) + v * (v1• v1)   // 式2
解這個方程得到:
u = ((v1•v1)(v2•v0)-(v1•v0)(v2•v1)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))
v = ((v0•v0)(v2•v1)-(v0•v1)(v2•v0)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))
是時候上代碼了,這段代碼同樣用到上面的Vector3類:




發佈了78 篇原創文章 · 獲贊 26 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章