【3D数学基础:图形与游戏开发】笔记 第13章 几何检测
作者:互联网
【3D数学基础:图形与游戏开发】笔记 第13章 几何检测
2D直线上的最近点
直线L表达式为p · n = d。
q是平面M上的某一点。
现在要在2D上找出距离平面M的最近点,很明显:如果将q和q`连接起来,这条连线将垂直于直线L。即q'是q在平面M上向直线L上的投影。
参数射线上的最近点
考虑在2D或3D中的参数射线R:p(t)=porg + td。
其中d是单位向量,参数t在0到l间变化,l是R的长度。对一给定点q,我们想要找出在R上离最近的点q的q‘。
这是一个简单的向量到向量的投影问题。设v为porg到q的向量。我们希望得到v在d上的投影,或v平行于d的部分。
点乘v · d的结果就是满足p(t)=q'的t值。即:
t = d · v
= d(q - porg)
q = p(t)
= porg+td
= porg + (d ·(q - porg))d
如果射线的定义是t从0到1变化,d不必是单位向量。那么在计算t值时必须除以d的模:
t = d(q - porg) / ||d ||
平面上的最近点
点到平面的距离
这个在几何图元中说过,不用知道p的位置就能计算出a。
我们今天要求的是q'这个点,可以用以下公式求得:
q' = q + (d - q · n)n
其实这个和2D直线上的最近点的计算公式是一样的。
圆或球上的最近点
求q距离圆/球上一点q'。
AABB上的最近点
在3D游戏中常用。
设B是由极值点pmax和pmin定义的AABB。对任意点q都能很容易地计算出在B上距离q最近的点q'。所用的方法是按一定顺序沿着每条轴将q“推向”B:
if (x < minX){
x = minX
}else if (x > maxX){
x = maxX
}
if (y < minY){
y = minY
}else if (y > maxY){
y = maxY
}
if (z < minZ){
z = minZ
}else if (z > maxZ){
z = maxZ
}
注意,如果q本来就在矩形边界框内部,代码运行的结果将返回原来的点。
相交性检测
在接下来的几节中,我们会介绍一系列相交性检测的方法。这些测试的目的是检测两个凡何图元是否交,在某些情况下还要求出相交部分。这些基本测试构成了碰撞检测系统的基础。碰撞检测用来防止物体互相穿越,或者使物体看起来好像互相被弹开。
我们将讨论两种不同类型的相交性检测。
- 静态测试:检测两个静止图元是否相交。它是一种布尔型测试—也就是说,测试结果只有真相交时)或假(不相交时)。如果两个图元相交,则可以获取更多的信息。但一般来说,这种测试的目的只是返回一个布尔值。
- 动态测试:针对的是两个运动图元,检测它们是否相交,及相交的时间点。运动值通常以参数形式来表达。因此,这种测试返回的结果不仅仅是一个布尔型的真/假值,还会返回一个指明相交时间点的值(参数t的值)。对于这里我们要讨论的测试,运动值是一个简单的线性位移——当t从0变化到1时原向量的偏移量。每个图元都可以有自己的运动值。然而,从单个图元的角度来考虑问题会比较简单。也就是说,一个图元被认为是“静止”的时个图元做了所有的“运动”。很容易做到这一点,只要将两个位移向量组合成一个相对位移向量,它描述了两个图元间的相对移动关系。因此,所有动态测试总是涉及一个静态图元和一个动态图元。
注意,包含射线在内的许多重要的测试实际上都是动态测试,因为射线能被看作一个运动的点。
在2D中两条隐式直线的相交性检测
这个简单,只需要解线性方程组就可以。
和其他方程组一样,存在3种可能性:
- 只有个解,这种情况下,公式中的分母为非零值。
- 无解,意味着直线是平行的,永远不会相交,分母等。
- 无穷多解,意味着两条直线重合,分母为零。
在3D中两条射线的相交性检测
r1(t1) = p1 + t1d1
r2(t2) = p2 + t2d2
同样存在三种可能性:
- 两条射线交于一点。
- 两条射线平行,没有交点。
- 两条射线重合,有无限多交点。
在3D中,还有第四种可能性:两条射线不在一个平面中,如图13.5所示:
射线和平面的相交性检测
在3D中射线与平面相交于一点。射线的参数定义为
p(t)=porg+td
平面以标准方式来定义,即对于平面上的所有点p,都满足:
p · n = d
尽管n和d常被限制为单位向量,但这里是没有必要加上这些限制条件的:
如果射线和平面互相平行,分母d为零,则它们之间没有交点。(我们仅讨论与平面的正面相交的情况。在这种情况下,仅当射线的方向和平面的法向量相反时才有交点,此时dm<0)。如果t超出了取值范围,说明射线和平面不相交。
三个平面间得到相交性检测
三个平面的方程为:
p · n1 = d1
p · n2 = d2
p · n3 = d3
如果任意一对平面平行,那么交点要么不存在,要么不唯一,在这两种情况下,公式13.7的分母都为零。
射线和圆球的相交性检测
射线的定义为:p(t)=po+td
这里,d为单位向量,t从0变化到l,l为射线长度。所要求的是交点处t的值:
这里有一些注意事项:
- 如果f为负,那么射线和圆不相交。
- 射线的起点可能在圆内,此时e2<r2。此时,根据不同的测试目的,会有不同的行为。
两个圆/球的相交性检测
静态检测
我们只需要确定d和两个半径之间的关系即可:
动态检测
假设一个球静止,另一个球运动:
计算方法如下:
这里有一些重要的注意事项:
- 如果||e||<r,则球在t=0时就相交。
- 如果t < 0 或 t > l,那么在所讨论的时间段内两个球不会发生接触。
- 如果根号内的值是负的,那么两个球不会相交。
球和平面的相交性检测
静态检测
球和平面的静态检测相对容易一些。可以用公式12.14来计算球心到平面的距离。如果距离小于球半径,那么它们相交。
即:d < r
动态检测
一样的,假设其中一个不动,另外一个做相对运动。
不管在平面上的哪点上发生相交,在球上的相交点总是定的,认识到这一点能大大简化问题。
这里要注意的是,由于球的位置是根据时间变化而变化的,所以问“球与平面相交”实际上就是“球运动多久后会与平面相交”,即我们知道会相交,只不过我们需要求的是相交的时间,公式如图所示。
射线和AABB的相交性检测
检测AABB和射线的相交性非常重要,因为根据检测的结果可以避免对更复杂物体的测试。(例如:我们要检测射线与多个由三角网格组成的物体的相交性,可以先计算射线和三角网格的AABB的相交性。有时候吋以一次就排除整个物体,而不必去检测这个物体的所有三角形。)
在附录B的参考资料[24]中,作者Woo提出-种方法:先判断矩形边界框的哪个面会相交,再检测射线与包含这个面的平面的相交性。如果交点在盒子中,那么射线与矩形边界框有相交,否则不存在相交。
AABB3中 raylntersect0就是用Woo的技术来实现的。有兴趣可以参阅源码。
射线和三角形的相交性检测
上面一步当射线与AABB相交以后,我们再判断射线是否真正打中物体,并且要知道打中了物体的哪个三角形面。
教材上的第278-280有代码实现。
两个AABB的相交性检测
可以用于检测两个物体是否有碰撞。AABB有相交则代表有碰撞,否则没有。
AABB的检测也分为动态的和静态的检测。
静态检测
静态检测比较简单,就检测AABB的每个维度上是否有重合即可。有一个维度重合即为相交。
动态检测
请参阅源码。可以在www.cngda.com上找到方法。
参考资料&原文链接
本文标签
游戏开发
、3D数学基础:图形与游戏开发
、Unreal Engine
、游戏开发基础
、数学
、游戏开发数学基础
、书籍笔记
、笔记
。
标签:13,检测,AABB,相交,射线,笔记,平面,3D 来源: https://www.cnblogs.com/sin998/p/15258254.html