Skip to content

Latest commit

 

History

History
121 lines (84 loc) · 2.73 KB

2015-05-02-空间内判断射线与球体相交.md

File metadata and controls

121 lines (84 loc) · 2.73 KB
title date status author
空间内判断射线与球体相交
2015-05-02
finished
jason82

在光线追踪中,我们常常需要进行ray-geometry相交检测,以此来计算照相机发射出来的每一条光线的颜色值,从而绘制出逼真的3D效果。几何物体的相交检测也是ray-tracing的最基本的步骤。

这次介绍的是ray-geometry里面最简单的ray-sphere的计算方法。

几何解析法

ray-sphere所用到的东西都是些几何向量的运算,涉及到三角函数和勾股定理等。我们可以先来看看示意图:

ray intersection

我们设球心位置为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的坐标。

数值解析法

ray intersection

我们知道球体的几何公式是,设球体半径为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

由于OCBRnb都是已知量,我们可以通过一元二次方程的公式解得到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