其他分享
首页 > 其他分享> > 【3D数学基础:图形与游戏开发】笔记 第13章 几何检测

【3D数学基础:图形与游戏开发】笔记 第13章 几何检测

作者:互联网

【3D数学基础:图形与游戏开发】笔记 第13章 几何检测

2D直线上的最近点

image-20210912093530782

直线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的部分。

image-20210912093923968

点乘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 ||

平面上的最近点

点到平面的距离

image-20210912094452606

这个在几何图元中说过,不用知道p的位置就能计算出a。

我们今天要求的是q'这个点,可以用以下公式求得:

q' = q + (d - q · n)n

其实这个和2D直线上的最近点的计算公式是一样的。

圆或球上的最近点

求q距离圆/球上一点q'

image-20210912095045923

AABB上的最近点

在3D游戏中常用。

image-20210912095253993

设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本来就在矩形边界框内部,代码运行的结果将返回原来的点。

相交性检测

在接下来的几节中,我们会介绍一系列相交性检测的方法。这些测试的目的是检测两个凡何图元是否交,在某些情况下还要求出相交部分。这些基本测试构成了碰撞检测系统的基础。碰撞检测用来防止物体互相穿越,或者使物体看起来好像互相被弹开。

我们将讨论两种不同类型的相交性检测。

注意,包含射线在内的许多重要的测试实际上都是动态测试,因为射线能被看作一个运动的点。

在2D中两条隐式直线的相交性检测

这个简单,只需要解线性方程组就可以。

image-20210912100405176

和其他方程组一样,存在3种可能性:

image-20210912100454173

在3D中两条射线的相交性检测

r1(t1) = p1 + t1d1

r2(t2) = p2 + t2d2

image-20210912100827046

同样存在三种可能性:

在3D中,还有第四种可能性:两条射线不在一个平面中,如图13.5所示:

image-20210912100803327

射线和平面的相交性检测

在3D中射线与平面相交于一点。射线的参数定义为

p(t)=porg+td

平面以标准方式来定义,即对于平面上的所有点p,都满足:

p · n = d

尽管n和d常被限制为单位向量,但这里是没有必要加上这些限制条件的:

image-20210912101333523

image-20210912101356095

如果射线和平面互相平行,分母d为零,则它们之间没有交点。(我们仅讨论与平面的正面相交的情况。在这种情况下,仅当射线的方向和平面的法向量相反时才有交点,此时dm<0)。如果t超出了取值范围,说明射线和平面不相交。

三个平面间得到相交性检测

三个平面的方程为:

p · n1 = d1

p · n2 = d2

p · n3 = d3

image-20210912101533008

image-20210912101629859

如果任意一对平面平行,那么交点要么不存在,要么不唯一,在这两种情况下,公式13.7的分母都为零。

射线和圆球的相交性检测

射线的定义为:p(t)=po+td

这里,d为单位向量,t从0变化到l,l为射线长度。所要求的是交点处t的值:

image-20210912101836490

这里有一些注意事项:

两个圆/球的相交性检测

静态检测

我们只需要确定d和两个半径之间的关系即可:

image-20210912102038746

动态检测

假设一个球静止,另一个球运动:

image-20210912102314524

计算方法如下:

image-20210912102334371

这里有一些重要的注意事项:

球和平面的相交性检测

image-20210912143337540

静态检测

球和平面的静态检测相对容易一些。可以用公式12.14来计算球心到平面的距离。如果距离小于球半径,那么它们相交。

即:d < r

动态检测

一样的,假设其中一个不动,另外一个做相对运动。

不管在平面上的哪点上发生相交,在球上的相交点总是定的,认识到这一点能大大简化问题。

image-20210912143819697

这里要注意的是,由于球的位置是根据时间变化而变化的,所以问“球与平面相交”实际上就是“球运动多久后会与平面相交”,即我们知道会相交,只不过我们需要求的是相交的时间,公式如图所示。

射线和AABB的相交性检测

检测AABB和射线的相交性非常重要,因为根据检测的结果可以避免对更复杂物体的测试。(例如:我们要检测射线与多个由三角网格组成的物体的相交性,可以先计算射线和三角网格的AABB的相交性。有时候吋以一次就排除整个物体,而不必去检测这个物体的所有三角形。)

在附录B的参考资料[24]中,作者Woo提出-种方法:先判断矩形边界框的哪个面会相交,再检测射线与包含这个面的平面的相交性。如果交点在盒子中,那么射线与矩形边界框有相交,否则不存在相交。

AABB3中 raylntersect0就是用Woo的技术来实现的。有兴趣可以参阅源码。

射线和三角形的相交性检测

上面一步当射线与AABB相交以后,我们再判断射线是否真正打中物体,并且要知道打中了物体的哪个三角形面。

教材上的第278-280有代码实现。

两个AABB的相交性检测

可以用于检测两个物体是否有碰撞。AABB有相交则代表有碰撞,否则没有。

AABB的检测也分为动态的和静态的检测。

静态检测

静态检测比较简单,就检测AABB的每个维度上是否有重合即可。有一个维度重合即为相交。

动态检测

请参阅源码。可以在www.cngda.com上找到方法。

参考资料&原文链接

猎豹网校:游戏开发之3D数学基础

本文标签

游戏开发3D数学基础:图形与游戏开发Unreal Engine游戏开发基础数学游戏开发数学基础书籍笔记笔记

标签:13,检测,AABB,相交,射线,笔记,平面,3D
来源: https://www.cnblogs.com/sin998/p/15258254.html