Algorithm 找出三维空间中的一个特定三角形是否可以从给定的点看到,并且可能有任意多个其他三角形

Algorithm 找出三维空间中的一个特定三角形是否可以从给定的点看到,并且可能有任意多个其他三角形,algorithm,function,3d,visibility,Algorithm,Function,3d,Visibility,我想写一个函数,如果一个三角形(由其顶点和法线指定)在3D空间中,从3D空间的给定点(由其x、y和z坐标指定)可见,则返回“True”,因为空间中的其他三角形可能充当“拦截器”,阻止您从该点看到指定的三角形 通过“看见”和“可见”,我的意思是可以用一条不与任何阻挡三角形相交的直线将三角形上的任何点连接到观察点 我已经研究了“z缓冲”和其他解决“可见性问题”的技术,但是,由于我没有将三角形渲染为像素,以便通过特定的视图端口在屏幕上显示,因此我认为这些是不相关的 我的两种方法是: 1) 从观察点通

我想写一个函数,如果一个三角形(由其顶点和法线指定)在3D空间中,从3D空间的给定点(由其x、y和z坐标指定)可见,则返回“True”,因为空间中的其他三角形可能充当“拦截器”,阻止您从该点看到指定的三角形

通过“看见”和“可见”,我的意思是可以用一条不与任何阻挡三角形相交的直线将三角形上的任何点连接到观察点

我已经研究了“z缓冲”和其他解决“可见性问题”的技术,但是,由于我没有将三角形渲染为像素,以便通过特定的视图端口在屏幕上显示,因此我认为这些是不相关的

我的两种方法是:

1) 从观察点通过潜在“阻挡”三角形的每个顶点投射一条线到某个非常大的半径(在我的应用程序中,没有三角形距离观察点超过1000个单位,所以我选择1001个单位)。然后,我将在traingle后面有一个区域,其边缘由我投影的线描述,其中无法看到物体。我会对所有拦截器执行此操作,然后找到所有这些区域的并集,并检查测试中的三角形是否位于创建的其中一个(可能是多个)区域内

2) 再次向所有阻挡三角形顶点发射线,找到这些线与测试三角形所在平面相交的点,以获得平面中每个阻挡三角形的投影三角形。将任何重叠的投影三角形合并为单个多边形。然后检查被测三角形是否完全位于任何投影三角形或合并多边形内

方法1)的问题在于,很难发现形状是否完全由三维体积包围,甚至更难将相交的三维体积组合成一个大的三维体积

方法2的问题)在某些情况下,通过阻挡三角形顶点的投影线永远不会击中感兴趣三角形的平面。我们也不能忽略这些情况,它们仍然可以遮挡感兴趣的三角形,它们只是在平面上投射一个无限长的阴影


我倾向于方法2,但就像我说的,这些方法似乎有点幼稚,如果有人能提出一个更优雅的解决方案,我会非常感兴趣!描述或伪代码是理想的,最终我希望在MATLAB或C++中实现这一点,但现在让我们保持一般性!p> 我也同意你的第二种方法,但要做一些修改

首先,假设你在某个平面上投影三角形。这里有几架飞机可供选择,但我不确定哪一架更适合你:

可以将所有三角形投影到测试的三角形平面。这样,如果您的封堵器三角形位于测试三角形的前面或后面,您可能很容易获得信息。缺点是,当你在测试三角形上观察掠射角时,数值误差会增大,可能会破坏你的解

下一个选项,我将从它开始,从6个轴对齐的平面中选择一个进行投影。把它们想象成天空盒子的墙壁。根据观察者和三角形的相对位置,您可以沿着距离最大的轴选择一个。此外,拾取轴对齐的平面可能会简化您的数学计算

下一个选项可能是使用一个与观察者和三角形中心之间的直线垂直的平面。当三角形以极端角度放置时,此选项可以最小化错误,但您需要自己进行测试

当你有你的测试三角形投影,你可以计算它的边界矩形-这是你感兴趣的领域,你不需要知道它以外的任何东西。您可以计算穿过观察者和矩形边界的4个平面,如典型的视锥体

当你投影你的遮挡三角形时,你建议把它们都连接成一个大多边形,但这样你可能会得到一个非常复杂的多边形。我会走相反的方向,从你们正在测试的投影三角形中减去投影遮光罩。在这种方法中,您不需要测试每个三角形组合,因为如果在任何一点上投影的三角形减少为空三角形-这意味着它已经被遮挡,无需测试其余的遮挡器

这是最重要的部分:

当然,唯一不可能以这种方式投影的三角形是那些在观察者后面至少有一个顶点(或者正好在侧面)的三角形。所以对于那些你可以用你的截锥剪裁平面来剪裁它们。一个三角形的裁剪结果可能包含很少的新三角形,但所有这些都将适合您在上面定义的感兴趣的区域

如果您决定做所有这些,请记住,您的封堵器可能落后于测试三角形,所以您需要对此作出解释。最简单的解决方案是用测试过的三角形平面剪裁它们,只留下前面的部分