光线和二次曲线相交的相对简单的类别:圆柱体,圆锥体,椭圆体,双曲面等。球体和平面是该族物体的特殊子类。 出于效率的缘由,这些简单的对象一般被赋予它们本身的相交实例。 例如,参见[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)