title | date | status | author |
---|---|---|---|
空间内判断射线与球体相交 |
2015-05-02 |
finished |
jason82 |
在光线追踪中,我们常常需要进行ray-geometry相交检测,以此来计算照相机发射出来的每一条光线的颜色值,从而绘制出逼真的3D效果。几何物体的相交检测也是ray-tracing的最基本的步骤。
这次介绍的是ray-geometry里面最简单的ray-sphere的计算方法。
ray-sphere所用到的东西都是些几何向量的运算,涉及到三角函数和勾股定理等。我们可以先来看看示意图:
我们设球心位置为A
,光线的起始点为B
,发射出上图一条红色的射线BC
。这样我们就可以作出辅助线如图黑色线段,为了方便标记,我们对线段进行必要的标记如下:
// 圆的半径 rad
rad = |AD|
// 向量B->A 记为 a
a = BA
// 向量B->C 记为 b
b = BC
// 向量 b 的单位向量 记为 nb
nb = normalize(b)
过点A
作辅助线AF
垂直于BC
,这样我们就可以得到直角三角形ABF
,通过勾股定理和向量内积我们可以得到向量BF
// 向量B->F 记为 r
r = |r|·nb
// 向量 r 的模长 |r| 其实就是向量 a 在 方向向量 nb 上的投影
|r| = a · nb
得到了向量r
,我们就可以计算出向量AF
// 向量A->F 记为 c
c = a - r
知道了向量c
、半径rad
,我们可以使用勾股定理计算出向量DF
的模长
// 向量D->F 记为 d
d = DF
// 根据勾股定理得
c*c + d*d = rad*rad
// 并且可知,当 c > rad 时,射线与球不相交
// 向量d的模长
d = sqrt(rad*rad - c*c)
// 我们知道向量 B->F,以及射线 B->C 的方向向量 nb
// 可知 D->F 记为 e
e = d*nb
BD = r - e
由此可计算出点D
和点E
的坐标。
我们知道球体的几何公式是,设球体半径为R
x^2 + y^2 + z^2 = R^2
我们设射线上点任意一点为P
,球心点为C
,可得等式
(P-C)^2 = R^2
因为点P
在直线BC
上,所以可以写成
P = B + t*nb
t
是一个标量,将等式中的P
代入得
(B+t*nb-C)^2 = R^2
t^2 + 2*nb(O-C)*t + |B-C|^2 - R^2 = 0
由于O
、C
、B
、R
、nb
都是已知量,我们可以通过一元二次方程的公式解得到t
的值。
a = 1
b = 2*nb(O-C)
c = |B-C|^2 - R^2
// 所以
det = b2−4ac
t = (-b ± sqrt(det)) / 2a
所以我们可以通过det
的值来判断公式是否有解:
如果det >= 0
则射线与球相交,否则不相交。
并且交点就等于
P = O ± t*nb