投影3D网格的2D轮廓算法

时间:2009-06-18 18:11:38

标签: math 3d geometry projection

给定:使用一组顶点和三角形定义的3D网格,用这些点构建网格。

问题:在任意平面上找到投影任意旋转网格的2d轮廓。

投影很容易。挑战在于找到平面中投影三角形边缘的“船体”。我需要一些关于研究这种算法的输入/指针的帮助。为简单起见,我们可以假设3D边缘直接向下投影到xy平面上。

7 个答案:

答案 0 :(得分:10)

  • 从最右边的点(具有最大x坐标的点)开始
  • 从这一点获取所有优势
  • 沿着与正x轴最小角度的边缘,并将其添加到解决方案集
  • 从达到的点开始,跟随并添加最小角度的边缘到您来自的边缘
  • 重复,直到达到原始点

答案 1 :(得分:3)

我只看到凸解的答案,所以这里是非凸的。 (这意味着什么有点令人困惑。)

从2D三角形中取出所有边并将它们分组。如果两条边共享两个端点,则它们位于同一组中。所有只有一条边的组都是shell的一部分。

最后,您可以将shell-edge组合成一个环,将它们连接在一起。

答案 2 :(得分:2)

此问题中提到的alpha形状技术处理顶点连接未知的一般点集:

Is there an efficient algorithm to generate a 2D concave hull?

但是,由于您已经知道可以通过投影保留的“面部”信息,因此可能不是最佳方法。

强力算法可能是可行的,尤其是在使用空间排序结构的情况下。例如,对于每个方面:

  1. 将平面投影到飞机上
  2. 检查投影面是否完全被现有几何体包围,如果是:完成(无需扩展投影轮廓)
  3. 如果点落在现有几何体之外,请执行三角形 - 三角形交叉点以确定哪些部分落在外面,构建任意n-gon(可能是凹形)以填充缺失的空间,然后将n-gon切入三角形
  4. 另一个想法,取决于你需要的保真度,只是从你的投影平面拍摄一束正常的几何光线。创建一个2d命中/未命中并使用它来确定您的范围。

答案 3 :(得分:2)

网格投影的2D轮廓是其边缘投影的子集。

使用此观察,可以使用以下方法确定2D轮廓:

  • 仅属于一个面的每条边的投影都是2D轮廓的一部分,
  • 对于其他边缘,确定其相邻面的法向量
  • 使用投影平面的法线计算那些法线的点积
  • 如果点积的所有符号不相同(这意味着,一个面指向投影平面,而至少另一个面没有指向边缘,则此边缘的投影属于2D轮廓)大纲的一部分)。

请注意,此方法将报告所有与投影平面正交的边,即使是从投影平面的视点看不到的边。例如,对于圆环,它将找到内部轮廓和外部轮廓,即使圆环以这样的方式旋转,使得其内部孔从投影平面的视点不可见。要弄清楚哪些边可见,您需要进行某种可见性测试。如果预期用途是用户显示,则可以使用使用正交投影矩阵计算的深度缓冲来从投影平面的视点渲染几何图形,并进行一些z测试以确定哪些边缘在平面上可见。如果需要精度,则需要执行光线/三角形交叉以确定可见性。

答案 4 :(得分:1)

添加:在投影中找到边缘的一种非常直观的方法是背面剔除!剔除和非剔除面之间的任何边缘应该是轮廓。如果要隐藏内部边缘,只需使用z缓冲区。背面剔除只是后投影顶点顺序,计算起来非常便宜。

答案 5 :(得分:0)

是否只是将xyz点投影到任意平面上的x'Y'点,然后在这些坐标中做一个凸包?

答案 6 :(得分:0)

  1. 找出x为min的点
  2. 找出该点的所有边
  3. 从这一点开始,想象你有一根棍子(绿色),它顺时针滚动以找到它遇到的第一个边缘。我们称之为边缘 A。 edge-A
  4. 在边 A 中寻找交叉点。找到导致相交的边B,我们称之为inter-A,这个inter-A是你的第二个轮廓点。 edge-B
  5. 然后让我们想想,在边缘 B 的两个点之间,谁是下一个轮廓点。链接inter-A 和起点然后我们可以“滚动棒”找到下一个轮廓点。 (候选人点1是那个) enter image description here
  6. 重复上述步骤,直到找到集合中已存在的点。

see a demo of finding outline for a bunny 这是上述算法的implementation