Loading

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

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

参考资料&原文链接

参考书籍:【3D数学基础:图形与游戏开发】 ISBN7-302-10946XTP.7262

(美) etcher Dun著、(美) an Arberry 清华大学出版社

GAMES101-现代计算机图形学入门-闫令琪

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

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

相交性检测

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

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

  • 静态测试:检测两个静止图元是否相交。它是一种布尔型测试—也就是说,测试结果只有真相交时)或假(不相交时)。如果两个图元相交,则可以获取更多的信息。但一般来说,这种测试的目的只是返回一个布尔值。
  • 动态测试:针对的是两个运动图元,检测它们是否相交,及相交的时间点。运动值通常以参数形式来表达。因此,这种测试返回的结果不仅仅是一个布尔型的真/假值,还会返回一个指明相交时间点的值(参数t的值)。对于这里我们要讨论的测试,运动值是一个简单的线性位移——当t从0变化到1时原向量的偏移量。每个图元都可以有自己的运动值。然而,从单个图元的角度来考虑问题会比较简单。也就是说,一个图元被认为是“静止”的时个图元做了所有的“运动”。很容易做到这一点,只要将两个位移向量组合成一个相对位移向量,它描述了两个图元间的相对移动关系。因此,所有动态测试总是涉及一个静态图元和一个动态图元。

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

在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

这里有一些注意事项:

  • 如果f为负,那么射线和圆不相交。
  • 射线的起点可能在圆内,此时e2<r2。此时,根据不同的测试目的,会有不同的行为。

两个圆/球的相交性检测

静态检测

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

image-20210912102038746

动态检测

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

image-20210912102314524

计算方法如下:

image-20210912102334371

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

  • 如果||e||<r,则球在t=0时就相交。
  • 如果t < 0 或 t > l,那么在所讨论的时间段内两个球不会发生接触。
  • 如果根号内的值是负的,那么两个球不会相交。

球和平面的相交性检测

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数学基础:图形与游戏开发Unreal Engine游戏开发基础数学游戏开发数学基础书籍笔记笔记

posted @ 2021-09-12 15:23  多思考多实践同等重要  阅读(372)  评论(0编辑  收藏  举报