Graphics 二次误差最小化网格简化算法中三角形折叠的处理

Graphics 二次误差最小化网格简化算法中三角形折叠的处理,graphics,geometry,mesh,simplification,Graphics,Geometry,Mesh,Simplification,最近,我正在实现QEM网格简化算法,该算法最初来自Michael Garland和Paul S.Heckbert的论文 根据该算法,我们应该为每条边计算一个收缩成本,并将所有边放入一个最小堆中,以便每次我们提取一条收缩成本最小的边。然而,收缩可能会导致入射三角形折叠,即收缩前后标准变化超过90度。折叠现象可以通过以下示例可视化: 假设我们获取的成本最低的边缘是V1V2,我们即将对其进行收缩。我们预计收缩将导致V1和V2合并,如图所示。更重要的是,如果我们将三角形的范数Tri(ABV2)定义为cr

最近,我正在实现QEM网格简化算法,该算法最初来自Michael Garland和Paul S.Heckbert的论文

根据该算法,我们应该为每条边计算一个
收缩成本
,并将所有边放入一个最小堆中,以便每次我们提取一条收缩成本最小的边。然而,收缩可能会导致入射三角形折叠,即收缩前后标准变化超过90度。折叠现象可以通过以下示例可视化:

假设我们获取的成本最低的边缘是
V1V2
,我们即将对其进行收缩。我们预计收缩将导致
V1
V2
合并,如图所示。更重要的是,如果我们将三角形的范数
Tri(ABV2)
定义为
cross\u乘积(V2A,V2B)
,我们可以发现这个范数的方向从指向外部变为指向内部。这不是我们想要的。文章说,如果遇到这种情况,我们应该“惩罚”这个操作,即在
V1V2
的成本中添加一个大的数字,使
V1V2
成为堆中的非顶部,这意味着此时它不会被提取。相反,我们将以最低的成本获得下一个优势

该算法可以使用以下伪代码编写:

while (number_of_left_edges > Pre_defined_number)
{
    Edge e = EdgeHeap.top();
    if (Check_edge_will_cause_foldover(e))
    {
         e.cost += A_VERY_LARGE_NUMBER;
         EdgeHeap.update();
    }
    else
    {
         e.Contract();
         Do_something_on_incident_triangles(e.Triangles);
         EdgeHeap.pop();
    }
}
然而,我发现了一个非常棘手的问题。如前所述,当我发现一条边
E1
的收缩可能会导致某些三角形的折叠时,我扩大了它的成本并将其扔回堆中,然后我选择了另一条边
E2
,仍然发现它会导致折叠。诸如此类。我没有发现一条边可以再收缩,所以循环无限继续,实际上没有边可以简化

有没有人能给我一些关于算法的提示,以便解决这个问题?非常感谢你


我知道这个问题很老,但你有没有找到解决办法?我也在想这个问题。在所示的示例中,一种解决方案可能是删除从B到V1V2的边,并添加一条新边以填充生成的涉及a的孔