在 3D 三角形网格上计算和显示色带的算法
Algorithm to calculate and display a ribbon on a 3D triangle mesh
我正在寻找解决以下问题的算法:
鉴于:
3D 三角形网格。网格代表地球表面的一部分。
顶点始终位于网格三角形的边或顶点上的多段线(一系列相连的线段)。折线表示地球表面道路的中心线。
我需要计算并显示道路,即在中心线的每一侧添加道路宽度的一半,计算网格相应三角形中的结果顶点,填充道路区域并勾勒出两侧的道路。
最简单的 and/or 最有效的策略是什么?如何最有效地存储道路数据?
我在这里看到 2 个选项:
渲染带有道路纹理的粗折线
渲染折线时需要 TBN 矩阵,因此请使用
- 折线正切为
tangent
- 表面法线为
normal
binormal=tangent x normal
将实际点p
位置移动到
p0=p+d*binormal
p1=p-d*binormal
并渲染纹理线 (p0,p1)
。这种方法与表面网格不精确匹配,因此您需要禁用深度或使用某种混合。同样在急转弯时,它可能会错过曲线的某些部分(在这种情况下,您可以渲染矩形或圆盘而不是直线。
通过将折线向边移动一半道路大小来创建网格
这会产生网格精确的道路拟合,但由于您的限制,在某些情况下,如果没有网格重新三角测量,道路的形状可能会非常扭曲。我是这样看的:
- 为每段道路投射 2 条线,将道路尺寸(绿色、棕色)移动一半
- 找到它们与当前道路控制点(红点)共享网格边的交点(水绿色点)
- 从交叉点获取平均点(洋红色点)并将其用作道路网格顶点。如果其中一个点在共享网格之外,请忽略它。如果两个交点都在共享边之外,则找到与不同边最近的交点。
如您所见,这在某些情况下会导致严重的道路厚度变形(交点之间差异很大,或者其中一个交点位于曲面网格边缘之外)。
如果您需要准确的道路厚度,请改用铸造线的交点作为道路控制点。为了能够在渲染时使用混合或禁用深度,或者通过重新三角化表面网格将此点添加到表面网格。粗略的这样的动作也会影响道路网格,你需要迭代几次...
另一种方法是对道路使用混合纹理(如精灵)并计算控制点的纹理坐标。如果道路太厚,则通过移动纹理坐标将其变薄...要完成这项工作,您需要 select 最远的交叉点而不是平均值...计算道路的实际一半大小并从计算纹理坐标。
如果你摆脱了道路顶点位于表面网格线段或顶点的限制(对于道路网格),那么你可以简单地单独使用移动线的交点。这将消除厚度伪影并大大简化事情。
我正在寻找解决以下问题的算法:
鉴于:
3D 三角形网格。网格代表地球表面的一部分。
顶点始终位于网格三角形的边或顶点上的多段线(一系列相连的线段)。折线表示地球表面道路的中心线。
我需要计算并显示道路,即在中心线的每一侧添加道路宽度的一半,计算网格相应三角形中的结果顶点,填充道路区域并勾勒出两侧的道路。
最简单的 and/or 最有效的策略是什么?如何最有效地存储道路数据?
我在这里看到 2 个选项:
渲染带有道路纹理的粗折线
渲染折线时需要 TBN 矩阵,因此请使用
- 折线正切为
tangent
- 表面法线为
normal
binormal=tangent x normal
将实际点
p
位置移动到p0=p+d*binormal p1=p-d*binormal
并渲染纹理线
(p0,p1)
。这种方法与表面网格不精确匹配,因此您需要禁用深度或使用某种混合。同样在急转弯时,它可能会错过曲线的某些部分(在这种情况下,您可以渲染矩形或圆盘而不是直线。- 折线正切为
通过将折线向边移动一半道路大小来创建网格
这会产生网格精确的道路拟合,但由于您的限制,在某些情况下,如果没有网格重新三角测量,道路的形状可能会非常扭曲。我是这样看的:
- 为每段道路投射 2 条线,将道路尺寸(绿色、棕色)移动一半
- 找到它们与当前道路控制点(红点)共享网格边的交点(水绿色点)
- 从交叉点获取平均点(洋红色点)并将其用作道路网格顶点。如果其中一个点在共享网格之外,请忽略它。如果两个交点都在共享边之外,则找到与不同边最近的交点。
如您所见,这在某些情况下会导致严重的道路厚度变形(交点之间差异很大,或者其中一个交点位于曲面网格边缘之外)。
如果您需要准确的道路厚度,请改用铸造线的交点作为道路控制点。为了能够在渲染时使用混合或禁用深度,或者通过重新三角化表面网格将此点添加到表面网格。粗略的这样的动作也会影响道路网格,你需要迭代几次...
另一种方法是对道路使用混合纹理(如精灵)并计算控制点的纹理坐标。如果道路太厚,则通过移动纹理坐标将其变薄...要完成这项工作,您需要 select 最远的交叉点而不是平均值...计算道路的实际一半大小并从计算纹理坐标。
如果你摆脱了道路顶点位于表面网格线段或顶点的限制(对于道路网格),那么你可以简单地单独使用移动线的交点。这将消除厚度伪影并大大简化事情。