分享一个小技巧,如何判断一个点是否在某个形状内部,可以是 2 维空间的图形,也可以是 3 维空间的物体。
方法:
- 从这个点向任意方向做一条射线;
- 如果这条射线与图形或物体相交的点数为奇数个,说明点在图形内部;
- 如果相交点数为偶数个,说明点在图形外部。
举例:
2 维示意图,3 维同理:
数学表示:
首先解释射线与球面的求交方法,推广到射线与一般隐式表面的求交方法,之后再解释射线与显式表面的求交方法以及优化加速办法。
射线与球面求交
射线的数学表示:
球面的数学表示:
联立射线表达式与球面表达式求交点:
t 的解可能有一个解、有两个解,或者无解,分别对应以下几种情况:
类似还可以推广到一般的隐式表面求解的情况。
一般隐式表面与射线求交点
一般隐式表面与射线的表达式:
联立隐式表面与射线表达式:
解出 t,t 要满足:
- 正数
- 实数
即为射线与隐式表面交点。
下面解释显示表面与射线的求交点方法:
显示表面与射线求交点:
首先从简单的思路引入,就是射线与全部三角形面逐个计算,判断是否相交,逐个计算交点,原始的思路是:
- 射线与三角形的所在平面进行求交(这里忽略射线正好与三角形面平行的情况)
- 判断交点是否在三角形内(之前文章解释过)
按照这种思路,首先定义平面的表达式,这里用法向量 N 和平面内的一点 P’ 来表示:
与射线方程联立:
解得:
再将得到得交点与三角形判断是否在三角形内即可。
优化1,下面介绍一种能够一步操作就得出交点是否在三角形内得方法。
主要思想是利用重心坐标(后边会补充文章介绍)与射线表达式联立,解出参数 t, b1, b2,根据解判断交点是否在三角形内,如下:
其中, t, b1, b2 的解法如下:
这样就能够一步判断射线与三角形的交点是否在三角形内了,但是如果对物体的每个三角形面都进行逐个计算的话,计算量是非常大的,每个像素都要对每个三角形面计算,下面进行加速优化:
优化2:使用轴对齐包围盒进行加速。
首先从二维引入:
这里射线与两个坐标轴方向的轴线分别相交,可以得到 tmin 和 tmax,再将两个轴向求出的 tmin 和 tmax 取交集,就得到了与二维包围盒的交点 tmin 和 tmax, 如下图所示:
拓展到三维情况下,包围盒可以看成三组对面夹出来的区域,按照以下的思路可以得到进入包围盒和离开包围盒的 t 。
- 只有全部对面都进入了,射线才进入到了盒子里;
- 只要射线离开了任何一对面,就说明已经离开了包围盒。
所以,盒子的进入时的 tenter,以及离开包围盒时的 texit,分别为:
讨论 t 为负数的情况:
- texit < 0 : 盒子在射线的背后,不可能有交点;
- texit > 0, tenter < 0 : 射线起点在盒子里面,一定有交点。
所以,当且仅当 tenter < texit && texit >= 0 的时候,射线和轴对齐包围盒有交点。