【问题标题】:Intersection of a mesh with a parametric surface网格与参数曲面的交集
【发布时间】:2013-06-10 20:42:24
【问题描述】:

我想知道如何编写一个精确的算法来计算参数表面 f : R^2 --> R^3 和三角网格之间的相交表面的边界。

我想到了第一种方法:

nStepsU = 100
nStepsV = 100
tolerance=0.01 // pick some sensical value
intersectionVertices={}
for  u from minU to maxU in nStepsU:
    for v from minV to maxV in nStepsV:
        for v in verticesInMesh:
             if euclidean distance( f(u,v), v ) < tolerance:
                 add vertex v in a set

connect the vertices in intersectionVertices with a line strip
draw the vertices in intersectionVertices

该算法非常简单但速度较慢 (n^3),并且没有考虑到网格的地形是基于三角形的,因此输出点是网格的点,而不是利用曲面相交计算的点与三角形并在很大程度上取决于必须设置的公差。

有人有更好的主意,或者可以带我去一个合适的图书馆吗?

【问题讨论】:

  • 您有关于表面的任何其他信息吗?你能有效地投影吗?你能有效地找到一个点在它的哪一边吗?
  • 表面是螺旋面x(r,theta) = r*cos(theta),y(r,theta) = theta,z(r,theta) = r*sin(theta) 所以无法区分里面和外面
  • 哦,对了。所以我的答案并不完全正确。但是您仍然可以从 (x,y,z) 确定 theta 和 r,并从中计算出有符号的距离。不过,我不清楚的是,您希望这有多精确?如果一个三角形在 y 方向上多次与曲面相交会怎样?

标签: opengl language-agnostic geometry collision-detection intersection


【解决方案1】:

我会遍历每个三角形,并计算三角形与曲面的交点。我会使用一个几何着色器,它将三角形作为输入,并输出线条。对于三角形中的每个顶点,计算到表面的有符号距离。然后遍历边:如果有两个顶点h 有不同的符号,则这些顶点之间的边与曲面相交。虽然我确信可以计算出确切的交集,但最简单的解决方案是线性插值,即

vec3 intersection = (h0 * v1 + h1 * v0) / (h0 + h1);

然后将每个交点输出为线段的一个顶点。

我发布的代码here 可以帮助您入门。如果您只想绘制结果,您可能会遇到我在该问题中描述的相同问题。如果需要客户端的顶点,可以使用transform feedback

编辑:我只是做了一个小测试。作为我使用的距离函数

float distToHelicoid(in vec3 p)
{
  float theta = p.y / 5 + offset.x / 50;
  float a = mod(theta - atan(p.z, p.x), 2*PI) - PI; // [-PI, PI[
  if (abs(a) > PI/2)
    a = mod(theta - atan(-p.z, -p.x), 2*PI) - PI;
  return a;
}

由于没有内部/外部,并且此距离函数从 -90° 变为 90°,因此您只能在符号从小负数变为小正数(反之亦然)时发射顶点,而不是从 90° 翻转时至 -90°。这里我只是过滤掉了 abs(dist) > 45° 的距离:

干净的方法是确定最近旋转的索引。例如。 [-pi, pi] 将是第 0 圈,[pi, 3pi] = 第 1 圈等。然后,只有两个距离指的是同一圈,您才会发射。

【讨论】:

  • 我喜欢你的方法,唯一的问题是我需要更好地研究几何着色器,因为我一直发现它们非常难以理解。我还认为,为了降低使用自定义顶点着色器的复杂性,该着色器将接近条件被尊重为红色的顶点着色。您是否有任何好的链接来记​​录如何将三角形上传到几何着色器?
  • 几何着色器从顶点着色器获取输入,因此您不必做任何与通常不同的事情。您只需附加一个几何着色器,而不是您的普通顶点+片段着色器程序。然后像往常一样使用该程序并绘制几何图形。所以它实际上很容易集成。请参阅 here 了解它如何适合管道。
  • @linello 我为螺旋体添加了一个距离函数。
  • 你的建议对我很有用。我已经设法让平面相交几何着色器工作,但我在模型视图矩阵和发射顶点的世界坐标方面遇到了问题。我的顶点着色器是一个简单的gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex,我总是得到带有错误z的顶点条,我应该如何编写顶点着色器?
  • 你有一个方程(x,y,z) = f(theta, r)。我正在做的是解决thetar。求解 theta 是最简单的,因为 y 仅线性依赖于 theta,并且与 r 无关:y=c*theta,所以theta=y/c。从几何上讲,我通过 (0,y,0) 和法线 (0,1,0) 将螺旋面与平面相交。要移动螺旋面,您需要偏移 y。或者,由于它们的线性关系,您可以抵消 theta。换句话说,向上平移螺旋体与在 y 轴上旋转它是一样的。
【解决方案2】:

如果您的曲面始终是螺旋面,您可以尝试将所有内容投影到围绕 Y 轴的圆柱体上。

螺旋面的表面由与圆柱体表面正交的线组成,投影后你会得到一个螺旋。将 3D 三角形网格投影到该圆柱体上后,您将获得 2D 三角形网格(请注意,某些区域可能会被多层三角形覆盖)。

因此,任务变成了在与螺旋相交的 2D 三角形网格中寻找三角形,这更简单。如果您对近似值满意,则可以分割该螺旋并使用某种树来找到与该螺旋相交的三角形。

当你有一个三角形与螺旋的一部分相交时,它的交点将是一个线段,你可以重新计算线段的 3D 坐标,这些线段的集合就是你的相交线。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多