确定球体是否与对象相交

时间:2010-02-08 06:36:36

标签: algorithm 3d theory

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

我已经考虑过3种方法来确定这一点,但每种方法都有它们的缺点,而且没有一种方法是理想的。

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

这样做的好处是它相当快,但由于我只计算谨慎点,所以它不是绝对的。如果我的网格的分辨率太高,那么球体有可能在我的网格节点之间的某个点处相交。

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

这样做的好处是它相当快,但也很容易失败。球体可以在三角形内与物体相交,并且一起错过所有顶点。

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

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

你们可能知道解决这个问题的算法或方法吗?我最重要的目标是准确性,我需要知道球体是否会接触物体。知道球体接触的位置或至少是一般区域也是很好的。最后,速度总是一件好事。

由于

-Faken

7 个答案:

答案 0 :(得分:5)

这应该是对你的问题的完整答案。我没有给出实施,所以可能需要考虑避免不必要的划分等。请询问澄清是否有任何不清楚。我在CashCommons的想法中建立了约翰。

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

有三种情况需要考虑:

  1. 最接近c的T中的点是T的顶点。这很容易!
  2. 最靠近c的T中的点位于T的内部。
  3. T中最接近c的点位于T的边缘之一。
  4. 我们定义了一些变量:

    • c:球体的中心
    • r:球体的半径
    • T:我们的三角形
    • v1,v2,v3:T
    • 的顶点
    • t:T中最接近c
    • 的点
    • P:包含v1,v2,v3
    • 的唯一平面
    • p:P中最接近c
    • 的点

    步骤1:检查所有三角形顶点,以防我们在案例1中。

    步骤2:找到p,P中最接近c的点。这可以通过将c投影到P

    来完成

    第3步:如果我们在案例2中,我们基本完成了。因此检查p是否在T中。(检查一个点是否在给定的三角形中相对容易,但我不知道最好的方法,所以我会把它留下来。)如果是,检查是否dist(p,c)> r,这会给你答案。

    这只留下了案例3。 因此,假设我们有p,并且p不在T中。现在,我们实际上从几何学中知道关于p的特定事物:线c - > p与P垂直(如果不是,我们可以找到一个比p更接近c的点p'。由于这种垂直性,我们可以使用毕达哥拉斯定理:

    Dist(c, z)^2 = Dist(c, z)^2 + D(p, z)^2

    对于P.中的任何z。特别是对于z = t。

    所以现在我们只需找到并检查是否:

    D(p,t)^2 <= r^2 - D(c,p)^2

    这是一个非常类似的问题,现在有两个方面。要做的是找到最接近p的T中的t,从而找到c。我们已经检查过t不在T的内部,或T的顶点之一。因此,它必须在其中一个边上。所以,我们可以尝试在每个边缘找到它。如果t不在顶点,那么线t - > p将垂直于边,所以它相当简单。

    步骤4:对于三角形的每一侧v1 - > v2,执行以下操作:

    4.1。从v1到v2的线段由

    给出
    (x,y,z) = (v1x, v1y, v1z) + s * (v2x - v1x, v2y - v1y, v2z - v1z), 0 <= s <= 1
    

    4.2我们想要一条位于平面P中的线,垂直于v1 - > v2,并且包含p。这一行的格式为

    (px, py, pz) + s * (qx, qy, qz)
    

    所以我们只需要选择一个与平面P平行且垂直于v1 - > v2的向量q。

    q = (p-->c) x (v1-->v2)
    

    (即,交叉积)应该这样做,因为它将垂直于P的法线,因此平行于P,并垂直于v1 - > v2。

    4.3求解方程组

    (tx,ty,tz) = (v1x, v1y, v1z) + s1 * (v2x - v1x, v2y - v1y, v2z - v1z)
    (tx,ty,tz) = (px, py, pz) + s2 * (qx, qy, qz)
    

    找到两条线上的t。这真的只是意味着解决

    v1x + s1 * (v2x - v1x) = px + s2 * qx
    v1y + s1 * (v2y - v1y) = py + s2 * qy
    v1z + s1 * (v2z - v1z) = pz + s2 * qz
    

    表示s1和s2。

    4.4。如果s1介于0和1之间,那么我们发现v1和v2之间的点t,应该检查它。

    4.5。如果s1不在0和1之间,那么v1或v2中的一个最接近p,所以我们已经检查了它。

答案 1 :(得分:1)

好的,我会再试一次。 ;)

如果你需要精确度,并且如果你准确地知道顶点,那么你可以使用shortest distance to a plane来查看球体是否接触任何由三个顶点组合定义的平面,这三个顶点可以为你提供三角形。对于那些做的人,你会看到最接近的点是否实际位于三角形内。

答案 2 :(得分:1)

我认为您可以使用CGAL执行此操作。首先计算球体和物体的Minkowski总和,然后您可以测试球体的中心(作为参考点)是否在物体内部或外部。这可以在任意精度算术中完成,因此如果需要,可以准确无误。

答案 3 :(得分:1)

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

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

  • 平面上最近的点位于三角形
  • 球体与三角形的至少一个边相交(因为连通性在平面/球体交叉点内存在从三角形内的某个点到三角形外的某个点的连续路径。该路径必须越过边界,它的作用点在于球体。)

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

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

  • 线上最近的点位于边缘
  • 球体与三角形的至少一个顶点相交。

因此,如果4个最近点(1个平面,3个线)中的任何一个位于球体和三角形中,那么它们当然会相交。否则:如果所有四个都在球体之外,那么两个不相交,如果它们中的任何一个在球体内,那么它们相交,如果三角形的任何顶点位于球体内。

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

当然,这可能效率不高 - 我不是编程几何的专家。正如Andrew McGregor所指出的那样,浮点计算并不一定能给出一致的结果。

答案 4 :(得分:0)

使用“边界体积”进行交叉检查可能会让您感兴趣。请检查this

这是一个page,用于调查表面交叉算法的算法。

欢呼声

答案 5 :(得分:0)

结合(2)并测试三角形面的中心作为另一个顶点是否适用于你?

答案 6 :(得分:0)

制作混合动力车。 找到闭合三角形/点whith方法2并检查三角形附近所有三角形的所有交点组合。