Algorithm 确定球体是否与对象相交

Algorithm 确定球体是否与对象相交,algorithm,3d,theory,Algorithm,3d,Theory,我有一个闭合的物体,由三角形的曲面表示来描述(由三个顶点来描述,这三个顶点形成一条右手法则,法线指向物体的“外部”)。我在3D空间中靠近物体表面的某个地方放置了一个半径一定的球体。我想确定球体是否与对象相交 我想了三种方法来确定这一点,但每种方法都有其缺点,没有一种是理想的 1) 我可以确定球体将要放置的“边”,从那里我可以计算从参考平面到物体第一次遇到的距离的网格。我可以对球体的另一侧做同样的操作,然后简单地检查到物体的距离是否总是大于到球体表面的距离。如果到对象的距离始终较大,则球体不会在栅

我有一个闭合的物体,由三角形的曲面表示来描述(由三个顶点来描述,这三个顶点形成一条右手法则,法线指向物体的“外部”)。我在3D空间中靠近物体表面的某个地方放置了一个半径一定的球体。我想确定球体是否与对象相交

我想了三种方法来确定这一点,但每种方法都有其缺点,没有一种是理想的

1) 我可以确定球体将要放置的“边”,从那里我可以计算从参考平面到物体第一次遇到的距离的网格。我可以对球体的另一侧做同样的操作,然后简单地检查到物体的距离是否总是大于到球体表面的距离。如果到对象的距离始终较大,则球体不会在栅格上的任何点与对象相交

这样做的好处是速度相当快,但因为我只计算离散点,所以它不是绝对的。如果栅格的分辨率太高,则球体有可能在栅格节点之间的某个点相交

2) 我可以取所有三角形的所有顶点,并对照我放置的球体方程检查它们。如果在球体内部检测到顶点,则球体绝对部分位于对象内部

这样做的好处是速度相当快,但也很容易失败。球体可能与三角形内的对象相交,并错过所有顶点

3) 我可以计算球体表面上的点簇。然后,我可以检查每个点是否在对象内部(使用多边形算法内部点的3D版本)。如果任何一点位于对象内部,则球体的一部分位于对象内部

这样做的好处是它可以非常精确,这取决于我在球体表面上使用了多少点(点的密度越高=精度越高)。但是,对象算法中的点相当昂贵,尤其是当三角形数量增加时。这种方法是最好的(甚至可以告诉我球体与对象相交的确切位置和多少),但速度非常慢

你们知道有什么算法或方法可以解决这样的问题吗?我的首要目标是准确性,我需要知道球体是否会接触到物体。如果知道球体接触到什么地方,或者至少是一般区域,那也很好。最后,速度总是一件好事

谢谢


-Faken

使用边界体积进行交叉点检查可能会引起您的兴趣。请查收

下面是一个关于曲面求交算法的综述

干杯将(2)和测试三角形面的中心作为另一个顶点对您有效吗?

好的,我再试一次


如果需要精确性,并且准确地知道顶点,则可以使用来查看球体是否接触由三个顶点组成的任意一组定义的平面,这三个顶点构成三角形。对于那些这样做的,你可以看到最近的接近点是否真的位于三角形内

我想你可以用这个。首先计算球体和对象的Minkowski和,然后可以测试球体的中心(作为参考点)是在对象内部还是外部。这可以用任意精度的算术来完成,因此,如果需要的话,可以精确。

球体和平面之间的交点是一个连通集

因此,采用John的“最接近平面”思想,如果球体和三角形相交,并且两者都闭合,则:

  • 平面上最近的点位于三角形内
  • 球体至少与三角形的一条边相交(因为通过连通性,平面/球体相交处存在一条从三角形内的某点到三角形外的某点的连续路径。该路径必须穿过边界,且其相交点位于球体中)

球体和直线之间的交点是一个连通集

因此,将边延伸到一条直线,就像我们将三角形延伸到一个平面一样。如果球体与边相交,则:

  • 线上最近的点位于边内
  • 球体至少与三角形的一个顶点相交
因此,如果四个最近点(一个平面,三条直线)中的任何一个位于球体和三角形中,那么它们当然相交。否则:如果所有四个都在球体外部,则两个不相交;如果其中任何一个在球体内部,则当三角形的任何顶点位于球体中时,它们相交

不幸的是,对每个三角形执行此操作只能告诉您球体和实体曲面是否相交。它不考虑球体完全位于固体内部的情况。因此,最后(或者首先),您还必须检查球体的中心是否在实体内部


当然,这可能不太有效——我不是几何编程专家。正如Andrew McGregor所指出的,浮点计算不一定能给出一致的结果。

这应该是对您问题的完整回答。我还没有给出一个实现,所以可能需要考虑避免不必要的划分等。如果有任何不清楚的地方,请要求澄清。我正在借鉴约翰在卡什康姆斯的想法

设c为半径为r的球体的圆心。我们真正需要知道的是:三角形T的任何一点(不仅仅是三个顶点)是否比r单位更接近c

有三种情况需要考虑:

  • T中最接近c的点是T的顶点。这很简单
  • whi中的要点
    (x,y,z) = (v1x, v1y, v1z) + s * (v2x - v1x, v2y - v1y, v2z - v1z), 0 <= s <= 1
    
    (px, py, pz) + s * (qx, qy, qz)
    
    q = (p-->c) x (v1-->v2)
    
    (tx,ty,tz) = (v1x, v1y, v1z) + s1 * (v2x - v1x, v2y - v1y, v2z - v1z)
    (tx,ty,tz) = (px, py, pz) + s2 * (qx, qy, qz)
    
    v1x + s1 * (v2x - v1x) = px + s2 * qx
    v1y + s1 * (v2y - v1y) = py + s2 * qy
    v1z + s1 * (v2z - v1z) = pz + s2 * qz