在 3D 三角形网格上计算和显示色带的算法

Algorithm to calculate and display a ribbon on a 3D triangle mesh

我正在寻找解决以下问题的算法:

鉴于:

  1. 3D 三角形网格。网格代表地球表面的一部分。

  2. 顶点始终位于网格三角形的边或顶点上的多段线(一系列相连的线段)。折线表示地球表面道路的中心线。

我需要计算并显示道路,即在中心线的每一侧添加道路宽度的一半,计算网格相应三角形中的结果顶点,填充道路区域并勾勒出两侧的道路。

最简单的 and/or 最有效的策略是什么?如何最有效地存储道路数据?

我在这里看到 2 个选项:

  1. 渲染带有道路纹理的粗折线

    渲染折线时需要 TBN 矩阵,因此请使用

    • 折线正切为tangent
    • 表面法线为normal
    • binormal=tangent x normal

    将实际点p位置移动到

    p0=p+d*binormal
    p1=p-d*binormal
    

    并渲染纹理线 (p0,p1)。这种方法与表面网格不精确匹配,因此您需要禁用深度或使用某种混合。同样在急转弯时,它可能会错过曲线的某些部分(在这种情况下,您可以渲染矩形或圆盘而不是直线。

  2. 通过将折线向边移动一半道路大小来创建网格

    这会产生网格精确的道路拟合,但由于您的限制,在某些情况下,如果没有网格重新三角测量,道路的形状可能会非常扭曲。我是这样看的:

    1. 为每段道路投射 2 条线,将道路尺寸(绿色、棕色)移动一半
    2. 找到它们与当前道路控制点(红点)共享网格边的交点(水绿色点)
    3. 从交叉点获取平均点(洋红色点)并将其用作道路网格顶点。如果其中一个点在共享网格之外,请忽略它。如果两个交点都在共享边之外,则找到与不同边最近的交点。

    如您所见,这在某些情况下会导致严重的道路厚度变形(交点之间差异很大,或者其中一个交点位于曲面网格边缘之外)。

    如果您需要准确的道路厚度,请改用铸造线的交点作为道路控制点。为了能够在渲染时使用混合或禁用深度,或者通过重新三角化表面网格将此点添加到表面网格。粗略的这样的动作也会影响道路网格,你需要迭代几次...

    另一种方法是对道路使用混合纹理(如精灵)并计算控制点的纹理坐标。如果道路太厚,则通过移动纹理坐标将其变薄...要完成这项工作,您需要 select 最远的交叉点而不是平均值...计算道路的实际一半大小并从计算纹理坐标。

    如果你摆脱了道路顶点位于表面网格线段或顶点的限制(对于道路网格),那么你可以简单地单独使用移动线的交点。这将消除厚度伪影并大大简化事情。