Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 检查边界框与视锥体的交点/碰撞_Python_Collision Detection_Bounding Box_Frustum - Fatal编程技术网

Python 检查边界框与视锥体的交点/碰撞

Python 检查边界框与视锥体的交点/碰撞,python,collision-detection,bounding-box,frustum,Python,Collision Detection,Bounding Box,Frustum,我想对照某些对象的轴对齐边界框检查视锥体,大致检查这些对象是否在视野中。速度不是什么大问题。我发现,构建视锥体的世界空间模型并检查其与bbox的碰撞是错误的方法。一个简单得多的方法是相反的方法,将给定bbox的每个顶点转换为屏幕空间,如果bbox的任何顶点在屏幕边界内,则将该bbox计算为可见。我通过乘以相机矩阵得到屏幕空间位置,然后根据相机的视野计算透视图 代码如下: vertexMatrix = matrix([vertex.x,vertex.y,vertex.z,1]) productM

我想对照某些对象的轴对齐边界框检查视锥体,大致检查这些对象是否在视野中。速度不是什么大问题。

我发现,构建视锥体的世界空间模型并检查其与bbox的碰撞是错误的方法。

一个简单得多的方法是相反的方法,将给定bbox的每个顶点转换为屏幕空间,如果bbox的任何顶点在屏幕边界内,则将该bbox计算为可见。我通过乘以相机矩阵得到屏幕空间位置,然后根据相机的视野计算透视图

代码如下:

vertexMatrix = matrix([vertex.x,vertex.y,vertex.z,1]) 
productMatrix = (vertexMatrix * camMatrix)
pVectSS = vector(prodMatrix[0][0],prodMatrix[0][1],prodMatrix[0][2])

pointX = ((pVectSS.x/(-pVectSS.z))/tan(radians(hFOV/2)))/2.0+.5
pointY = ((pVectSS.y/(-pVectSS.z))/tan(radians(vFOV/2)))/2.0+.5
关键:


那就行了。然而,通常人们宁愿提取平截头体平面并计算到这些平面的距离。你说“速度不是什么大问题”,但最终你可能会发现它是。毕竟,我们可以通过截锥剔除来加快速度

将一个顶点与一个矩阵相乘需要4个点积的等价物,因此需要32个点积的等价物来检查所有8个角点。计算点到平面的距离需要点积和加法,这在最坏的情况下效率更高,在平均情况下效率更高(因为在一个或两个平面后剪裁对象后,通常可以丢弃对象,但不能超过三个平面)。对于利用临时一致性的剪辑平面,有许多优化,我将不详细介绍这些优化


此外,可以通过计算中心点到平面的距离,并检查该距离是否大于边界框的半径,预先执行一些粗略剔除。这将以极低的成本剔除明显“入”或“出”的对象。或者,作为第一次超粗检查,您可以将视图向量的点积与视野值的余弦加上一些“填充”(或者,只是看看它是否为正)进行比较。你会记得,两个向量的点积告诉你它们指向同一方向的程度。在你的视图向量中有一个负点积的东西当然可以安全地丢弃,因为它就在你身后。

我应该解释一下为什么在这种情况下速度不是一个因素;该脚本用于预处理3d场景,以确定要导出到光线跟踪渲染器的对象,因此在方案中,它的运行速度并不重要,只是实现速度:)。我的回答实际上也有点错误,因为有一个边缘的例子,一个大的物体靠近相机,它的顶点都在视野之外,所以我最终只是在世界空间一号周围画了一个屏幕空间bbox,这是一个相当糟糕的技巧,但现在已经足够好了。对于光线跟踪器,即使只是边界上的一小部分碎片也可能造成巨大的差异。您可以考虑使用OpenGL绘制场景(如果需要的话,可以使用固定的功能,因为速度并不重要,而且很简单),并且为每个对象运行一个遮挡查询(几乎每一个图形卡都支持至少十年的时间)。没有z测试,所以透明对象不会完全剔除它们后面的内容,我们对漂亮的渲染不感兴趣。我们只需要在查询中为任何绘制了多达一个片段的对象提供一个正数。不过我想到的另一件事是:那些被剔除的对象(无论采用何种方法)如何,但无论如何都是需要的?当有人说“光线追踪”时,首先想到的是有反射的闪亮的东西。当对象远离视锥台时,可以很好地在反射曲面中看到它。这在某些情况下可能不太明显,但在其他情况下会产生非常有趣的效果,尤其是在动画中。如果这可能是一个问题,你不应该放弃场景导出中的任何内容。是的,你是对的,在这种情况下,有必要剔除对象,因为每个对象都在300万多边形的区域内,加上所有反射都是非常漫反射的,因此它们不会特别受到远处对象的影响。光线跟踪器不想剔除对象本身,因为正如您所说,反射对象通常会受到屏幕外对象的影响。
 camMatrix = camera inverse world-space matrix
 pVectSS = position vector screen-space
 hFOV = horizontal field of view
 vFOV = vertical field of view