射線與三角面相交判定

2021-08-20 17:21:42 字數 2084 閱讀 3610

**

射線表示:

o + d *t

三角表示:

v0 + (v1 - v0)*u + (v2 - v0) * v

u >= 0;

v >= 0;

u + v < 1; 

如果射線相交在三角內,則:

o + d *t = v0 + (v1 - v0)*u + (v2 - v0) * v

u >= 0;

v >= 0;

u + v < 1; 

分析:uvt是3個未知數, v0,v1,v2,o,d是已知向量,是個3階行列式,可求uvt

可以做簡化

e1 = v1 - v0;

e2 = v2 - v0;

t = o - v0;

o + d *t = v0 + (v1 - v0)*u + (v2 - v0) * v

=》- d *t + e1*u + e2 * v = t

=》|-d  e1 e2| t = t

|               | u 

|               | v  

三階行列式求解(克萊姆法則)

=》t = det|t e1 e2| / det|-d e1 e2|  

u = det|-d t e2| / det|-d e1 e2|  

v = det|-d e1 t| / det|-d e1 e2| 

下面的推導只是為簡化函式   

根據混合積公式(等價的代數余子式表示方法)  

det|a b c| = axb *c = bxc *a = -axc *b  //這裡3種轉換,只是為後面簡化成pq更方便

=》t = txe1 *e2 / dxe2 *e1

u = dxe2 *t  / dxe2 *e1

v = txe1 *d  / dxe2 *e1

簡化p = dxe2

q = txe1 

=》t = q *e2 / p *e1

u = p *t  / p *e1

v = q *d  / p *e1

函式實現:

bool intersecttrangle(

const vec3& o, const vec3& d,

const vec3& v0, const vec3& v1, const vec3& v2,

float& t, float& u, float& v)

else

if(det < 0.0001f)

return false;

u = dot(p, t);

if(u < 0 || u > det)

return false;

vec3 q = cross(t, e1);

v = dot(q, d);

if(v < 0 || u + v > det)

return false;

t = dot(q, e2);

float invdet = 1.0f / det;

t  *= invdet;

u *= invdet;

v  *= invdet;

return true;

}**說明:

1,裡面有很多if為了提高**效率,

2,確保det>0,如果det<0則令det = -det,並對t做相應的調整,這樣做是為了方便後續計算,否則的話需要分別處理det>0和det<0兩種情況。

3,if(det < 0.0001f) 此時無解,三角與射線近乎平行,注意浮點數和0的比較,一般不用 == 0的方式,而是給定乙個epsilon值,並與這個值比較。

4,u = dot(p, t);這裡實際上u還沒有計算完畢,此時的值是dot(p,t),如果dot(p,t) > det, 那麼u > 1,無交點。

5,要確保u + v <= 1,也即 [dot(p,t) + dot(q, d)] / det 必須不能大於1,否則無交點。

交點座標:

根據上面**求出的t,u,v的值,交點的最終座標可以用下面兩種方法計算

o + dt

(1 - u - v)v0 + uv1 + vv2  

*/

射線與三角型 多邊形相交測試

乙個點是否在多邊形裡面,只將這個點向任意方向作乙個射線,若與這條射線有奇數條邊相交則點在多邊形裡面,如果有偶數條邊相交則在外面 實際上兩個三角形合在一起,是乙個四邊形,對於這種多個圖形合在一起的圖形不要做公共邊的測試就行了,把他當成乙個多邊形 或者兩個三角形分開來測試也行。gameres論壇上的co...

圓與三角形(圓與三角形是否相交)

給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出 yes 否則輸出 no 三角形的面積大於0 第1行 乙個數t,表示輸入的測試數量 1 t 10000 之後每4行用來描述一組測試資料。4 1 三個數,前兩個數為圓心的座標xc,yc,第3個數為圓的半徑r。3000 xc,yc ...

13 三角形判定

數學家告訴我們 三角形中,任意兩條邊之和一定大於第三邊。請寫乙個程式,輸入為三條線段的長度,輸出yes或者no代表這三條線段能否組成乙個三角形。輸入三條邊長a,b,c 如果 a加b大於c 並且 b加c大於a 並且 c加a大於b 就輸出yes 否則輸出no 輸入格式 輸入共一行,三個整數,代表三條線段...