我想知道如何编写精确的算法来计算参数曲面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)并且没有考虑到网格的地形基于三角形,因此输出点是网格的点,而不是利用表面的交点计算的点使用三角形并且严重依赖于必须设置的公差。
有人有更好的想法,还是可以为此目的驱使我到合适的图书馆?
答案 0 :(得分:3)
我将迭代每个三角形,并计算三角形与曲面的交点。我会使用几何着色器将三角形作为输入,并输出线条。对于三角形中的每个顶点,计算到曲面的有符号距离。然后迭代边缘:如果有两个顶点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等等。如果两个距离指的是相同的旋转,则只会发射。
答案 1 :(得分:1)
如果表面始终是螺旋面,则可以尝试将所有内容投影到Y轴周围的圆柱体上。
螺旋面由垂直于该圆柱表面的线组成,投影后将得到螺旋线。在将3D三角形网格投影到该圆柱体上之后,您将获得2D三角形网格(请注意,某些区域可能会被多层三角形覆盖)。
因此,任务变得在2D三角形网格中找到与螺旋相交的三角形,这更简单。如果您对近似值没有问题,可以对该螺旋进行分段并使用某种树来查找与螺旋相交的三角形。
当你有一个与螺旋部分相交的三角形时,它的交点将是一个线段,你可以重新计算线段的3D坐标,这些线段的集合就是你的交叉线。