3D空間中射線與三角形的交叉檢測演算法

2021-07-09 05:25:36 字數 1453 閱讀 8859

射線ray,在3d圖形學中有很多重要的應用。比如,pick操作就是使用射線ray來實現的,還有諸如子彈射線的碰撞檢測等等都可以使用射線ray來完成。所以,在本次部落格中,將會簡單的像大家介紹下,如何進行ray-********的交叉檢測。

在tomas moller的mt97**中,提出了一種新的演算法。這種演算法能夠減少以前進行ray-********交叉檢測所需要的記憶體消耗。在以前,進行ray-********交叉檢測,主要是計算射線與三角形所構成的平面的交點,然後重新判斷交點是否在三角形上,從而來判斷是否發生了交叉。這種方法很直觀,符合我們一直以來所學的數學知識。但是,這種檢測方法進行的計算較多,而且還需要根據三角形來求它所在的平面,這樣又需要進行計算,同時也需要另外開闢空間來儲存計算出來的平面。

數學之美,就在於能夠找到其他的方法來代替這種顯而易見的方式,從而將問題簡化到一定的程度。這種簡化的過程,不需要在**中實現,只需要我們事先根據條件,然後在草稿紙上計算出最後的結論,我們只需要在我們的**中直接使用最終得到的結論即可。

在tomas moller的**中,它提到了這樣的乙個概念:

如果乙個點在三角形v0, v1, v2上,那麼這個點就可以用如下的方式來表示:

t(u, v) = (1 - u - v) * v0 + u * v1 + v * v2 ;

這裡u+v <= 1, u >= 0 ,  v >=0

而對於射線,我們一般使用如下的方程來表示它:

r (t)= o + t * d ; (o為射線的起始點,d為射線的方向)

所以,既然他們要有交點,我們就能夠直接使用如下的方法來得出:

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

然後在進行一系列的變換,最終得到結果。感興趣的讀者可以自行閱讀tomas moller的**,**中詳細的解釋了推導過程。這裡不再贅述。

以下是ray-********交叉檢測演算法的moller演算法實現,基本上就是tomas moller**中**的拷貝,如下所示:

[cpp]view plain

copy

bool

ray::intersectwith********(vector3 v0,vector3 v1, vector3 v2,  

bool

bcull,   

float

*t)  

else

return

true

;  }// end for intersectwith********

這個圖是在沒有發生交叉的時候的情況,

下圖是在發生了交叉之後的截圖:

3D空間中射線與三角形的交叉檢測演算法

射線ray,在3d圖形學中有非常多重要的應用。比方,pick操作就是使用射線ray來實現的,還有諸如子彈射線的碰撞檢測等等都能夠使用射線ray來完畢。所以,在本次部落格中,將會簡單的像大家介紹下。怎樣進行ray 的交叉檢測。在tomas moller的mt97 中,提出了一種新的演算法。這樣的演算法...

學習OpenGL (四) 3D空間中的三角形

gl s圖元通過連線三個頂點繪製三角形,得到如圖所示的三角形 頂點的指定次序以及方向的組合稱為環繞,圖中三角形是被認為具有順時針方向的環繞。在預設情況下,opengl認為逆時針方向環繞的一面是多邊形的正面,因此圖中的三角形為圖形的反面。如果想改變opengl這一預設行為,可以呼叫如下函式 glfro...

射線與三角形求交的計算

將射線定義為乙個基點和向量,那麼射線上的任意點可以表示為p p0 tv,其中p0為基點,v為向量,t滿足 t 0.採用重心座標定義三角形,三角形上的任意點可以表示為 p w v0 u v1 v v2,其中u v w 1.由此,將射線方程代入上式,則 p0 tv 1 u v v0 uv1 vv2.利用...