原部落格位址空間中直線段和三角形的相交演算法
最近在看recast&detour原始碼的時候有遇到許多數學上的演算法問題,特此記錄,以便以後檢視。
分析問題: 已經線段pq (p起點 q終點) ,三角形abc(a b c逆時針儲存),判斷pq與abc有無交點。
第一步:
判斷三角形所在的面和線段所在的直線 是否平行 或者 是否是從三角形面的背面進入。如果是就提前退出,否則進入第二步。
(使用面的法向量 和 線段的向量 的 點積)
平面的方程可以表示為:
x*normal = d (1)
其中 x 為平面上的點,d為原點到平面的距離。
以p為起點的,沿著pq方向的射線上的點的座標可以表示為:
m = p + t*pq = p - t*qp (2)
假設m點即為 平面與pq所在的直線的交點:(m點和a點均為在平面上的點,帶入公式(1)中
(op→−t⋅qp→)⋅normal−→−−−−=oa−→⋅normal−→−−−−
(op→−t⋅qp→)⋅normal→=oa→⋅normal→
解得t為
t=ap−→⋅normal−→−−−−qp→⋅normal−→−−−−
t=ap→⋅normal→qp→⋅normal→
判斷t是否 (0,1)之間,如果是繼續第三步,如果否返回false。
第三步:
判斷是否交點在三角形內部。
三角形abc內的點m可以用三角形的重心座標系表示 :
m=(1−λ2−λ3)a+λ2b+λ3c
m=(1−λ2−λ3)a+λ2b+λ3c
其中如果lamda3 和 lamda2 都在(0,1)之間,那麼表示m在abc的內部
改寫成向量形式,且把m用公式(2)帶入,得到:
op→−tqp→=(1−λ2−λ3)oa−→+λ2ob→+λ3oc→
op→−tqp→=(1−λ2−λ3)oa→+λ2ob→+λ3oc→
λ2ab→+λ3ac→+tqp→=ap−→
λ2ab→+λ3ac→+tqp→=ap→
寫成向量的形式:
⎛⎝⎜abxabyabzacxacyaczqpxqpyqpz⎞⎠⎟⎛⎝⎜λ2λ3t⎞⎠⎟=⎛⎝⎜apxapyapz⎞⎠⎟
(abxacxqpxabyacyqpyabzaczqpz)(λ2λ3t)=(apxapyapz)
求解lamda2 lamda3:(應用tips中的克萊姆法則以及混合積的運算法則)
λ2=(ap,ac,qp)(ab,ac,qp)=ac⋅(qp×ap)qp⋅(ab×ac)λ3=(ab,ap,qp)(ab,ac,qp)=ab⋅(ap×qp)qp⋅(ab×ac)=−ab⋅(qp×ap)qp⋅(ab×ac)
λ2=(ap,ac,qp)(ab,ac,qp)=ac⋅(qp×ap)qp⋅(ab×ac)λ3=(ab,ap,qp)(ab,ac,qp)=ab⋅(ap×qp)qp⋅(ab×ac)=−ab⋅(qp×ap)qp⋅(ab×ac)
原始碼// 空間點 sp 起點 sq終點
// 三角形空間點 a b c
// 輸出引數 t
static bool intersectsegment********(const float* sp, const float* sq,
const float* a, const float* b, const float* c,
float &t)
tips
克萊姆法則
乙個線性方程組可以用矩陣(a為n*n的方陣)與向量(x,c均長度為n的列向量)的方程來表示:
ax=c
ax=c
如果 a是乙個可逆矩陣,那麼方程有解,為
xi=det(ai)det(a)
xi=det(ai)det(a)
其中ai是被列向量 c取代了 a的第i列的列向量後得到的矩陣。
混合積的運算法則
1.混合積和三維矩陣行列式的關係(其中 後乙個等號 矩陣的轉置矩陣的行列式等於這個矩陣的行列式。)
a⋅(b×c)=∣∣∣∣a1b1c1a2b2c2a3b3c3∣∣∣∣=∣∣∣∣a1a2a3b1b2b3c1c2c3∣∣∣∣
a⋅(b×c)=|a1a2a3b1b2b3c1c2c3|=|a1b1c1a2b2c2a3b3c3|
2.混合積的交換律
a⋅(b×c)=b⋅(c×a)=c⋅(a×b)
a⋅(b×c)=b⋅(c×a)=c⋅(a×b)
圓與三角形(圓與三角形是否相交)
給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出 yes 否則輸出 no 三角形的面積大於0 第1行 乙個數t,表示輸入的測試數量 1 t 10000 之後每4行用來描述一組測試資料。4 1 三個數,前兩個數為圓心的座標xc,yc,第3個數為圓的半徑r。3000 xc,yc ...
經典演算法 (三)帕斯卡三角形(楊輝三角形)
楊輝三角,是二項式係數在三角形中的一種幾何排列。在歐洲,這個表叫做帕斯卡三角形。帕斯卡 1623 1662 是在1654年發現這一規律的,比楊輝要遲393年,比賈憲遲600年。簡介 楊輝三角,是二項式係數在三角形中的一種幾何排列。在歐洲,這個表叫做帕斯卡三角形。帕斯卡 1623 1662 是在165...
三角形填充演算法
這個演算法的精妙之處在於把求斜率的部分改為了插值計算,解決了浮點數的問題。整個部分並沒有直接去求直線的斜率。能用 解釋的盡量不bb,見 private function draw easy p1 point,p2 point,p3 point,color uint 0 void p3.y if p1...