光線和二次曲線相交的相對簡單的類別:圓柱體,圓錐體,橢圓體,雙曲面等。球體和平面是該族物體的特殊子類。 出於效率的緣由,這些簡單的對象一般被賦予它們本身的相交實例。 例如,參見[13]以得到更快的圓柱交點方法。 本節將介紹這些對象的廣義相交。 一樣,參數光線公式和隱式表面方程用於解決相交問題。 標準映射在本節末尾討論。算法
5.1 光線/二次曲面 相交編程
定義光線:函數
使用[4]中的公式,二次曲面表面方程爲:測試
矩陣標記爲Q,在二次曲面上用於執行變換和其餘運算。 有關這些操做的進一步討論,請參見[6]和[4]。 該等式等效於函數F(X,Y,Z)= 0的狀況:spa
將(G1)代入(G2),求解t,獲得二次方程的係數:3d
若是Aq!= 0,則檢查平方判別式。 若是△<0,則不發生交叉。 不然,若是須要,計算t0和可能的t1。 t的最小正值用於計算最近的相交點:對象
若是Aq = 0。那麼就很簡單了:blog
一旦計算出t,就使用等式(C8)計算交點ri。 經過取函數F相對於X,Y和Z的偏導數來造成二次曲面的法線:內存
請注意,rn未標準化。 乘以2能夠刪除,由於此時法線的長度並不重要。 此外,法線應該在面向光線的表面,所以該矢量的方向必須根據其與方向矢量Rd的關係而反轉。 若是rn點乘Rd> 0,那麼法線應該反轉。效率
效率問題
有一些技術能夠應用到這個算法中,使其在計算上更有效率。一個重要的思想是把方程中的公約數提出來。這就形成了看起來不那麼優雅的公式,但對於效率來講,這並不重要。例如,能夠重寫計算(G3)中的Aq的公式
這樣就消掉了3個相乘。另外一個簡單的變化是將全部的常數乘(即:2 * ....)將因素轉化爲給定的因素,根據須要創造新的因素。只有當內存約束不是問題時,才建議這樣作。最後,以相似於(A16)的方式修改二次方程將節省一些操做。實質上,將NBq=Bq/2代入式(G3)求解。
Kernighan和Plauger的[10]基本編程規則是「寫得清楚——不要太聰明」,這應該與Press的發言[11]相平衡,「 (計算機)革命來了,全部犯有此類(不考慮因素的)犯罪行爲的人都會被當即處決,但他們的程序不會!」一個好的方法是仔細地註釋任何因爲效率緣由而產生的混淆公式。
合併全部這些更改將致使修改(G3)
因爲效率的緣由,正常的計算能夠避免交叉例程[16]。在全部被測試的表面中,只有一個表面與射線的原點最近,這意味着這個物體將是惟一一個與射線的原點相關的物體。對於計算,若是須要,能夠計算法線。
必須再次解決浮點運算不精確的問題。 這種不精確性影響Aq和Bq的測試幾乎等於0.還必須解決在二次曲面上開始射線原點的狀況。 請參閱「光線/球體交點」部分中的「精確度問題」以查找問題及其可能的問題。 建議使用[11]第5.5節中給出的二次公式計算,以幫助避免精度問題。
算法步驟以下:
1,計算係數
2,若是Aq不等於0,計算Ka和Kb
3,若是Ka2-Kb小於0,無解
4,計算交點距離t0或t1
5,計算交點
6,計算法線,無標準化和符號改變的
7,重定向法線
8,標準化法線
5.2 標準逆映射
如何從二次曲面交點到(u,v)參數空間執行逆映射主要是一個選擇問題。 對於較少使用的二次曲面,例如雙曲面片,尤爲如此。 可是,在實體建模和其餘具備標準映射定義的計算機圖形相關字段中使用了對象。 這裏包括這些算法,由於它們能夠輔助圖形功能,例如紋理映射以及許多非圖形應用程序。 未涵蓋將參數座標映射到世界座標,由於在大多數光線跟蹤應用程序中一般不須要此映射。
圓的逆映射
圓的逆映射主要是一個從笛卡爾座標系到極座標變換的問題。在XY平面上定義一個圓,圓心在原點,半徑爲Cr
顯然,在一個環境中,圓的方向和位置與這個簡單的定義不一樣。假設某個變換矩陣與圓相關聯,使圓和相關數據與定義相一致。
給定一個交點Ri:
在XY平面上(Zi=0)(u,v)座標定義爲u從(0..1)開始,從+X軸向+Y軸移動,v從(0. 1)開始,從原點到圓的邊緣。這個映射如圖12所示。這些參數由Ri計算以下:
注意,咱們能夠經過設置Cr=1來消除一個乘法和一個除法。這能夠經過將一個縮放矩陣鏈接到較早的變換矩陣中來實現,從而使圓是一個單位圓。
柱面的逆映射
定義半徑爲Cr,高度爲Ch的圓柱體:
還有一個交點Ri vec | i (u,v)座標定義爲u從(0..1)開始,從+X軸向+Y軸移動,v從(0..1)開始,從(0..1)到圓柱體的頂部。這個映射如圖13所示。這些參數的計算以下
椎體的逆映射
定義一個高爲Ch半徑爲Cr0,Cr0在Z=0, Crh,在Z=Ch
還有交點Ri。(u,v)座標定義爲u從(0…1)開始,從+X軸向+Y軸移動,v從(0…1)到圓柱體的頂c。這個映射如圖14所示。這些參數的計算方法以下:
或者,你能夠計算圓。 請注意,能夠對錐體進行屢次劃分和從新使用。 另外,請注意,當Cr0 = 0且Zi = 0(或Crh = 0且Zi = Ch)時,將致使除以零。 此時u未定義,能夠任意賦值(0 ..1)