【表面重建】第一篇:delaunay三角化(未完)

文章目录

  • 一、声明
  • 二、算法流程
  • 三、Delaunay三角片的特性
  • 四、实现delaunay算法的分类
    • 生长算法
    • 逐点插入算法
    • 分治算法
    • 基于Bowyer-Watson算法
  • 五、代码
    • 调用scipy的API
    • 调用cgal的API
  • 六、参考来源

一、声明

  • 本帖持续更新中
  • 如有纰漏望指正!
  • 作者会尽量归结一些自己的理解,希望能对读者有所帮助。另外,为了尊重原作者本帖引用的地方会尽量加入引用。

二、算法流程

Delaunay 三角化是一种常用于表面重建的算法。其基本流程如下:

  1. 输入数据:Delaunay 三角化算法的输入通常是一组二维或三维的点集。在三维表面重建中,这些点集代表物体表面的样本点。

  2. 建立初始三角化:算法首先在点集中选择几个点,建立一个初始的三角化结构。在二维情况下,这可能是一个超级三角形,包含了所有的样本点;在三维情况下,则可能是一个四面体。

  3. 增量添加点:算法逐个将剩余的点插入到当前的三角化结构中。每次插入一个点后,都会更新三角化结构,确保Delaunay条件得到满足。

  4. 满足Delaunay条件:Delaunay 三角化要求每个三角形(或四面体)的外接圆(或外接球)不包含其他的点。当新的点被添加到三角化结构时,可能会违反这个条件。此时,算法会通过翻转三角形的边(或四面体的面)来调整结构,重新满足Delaunay条件。

  5. 去除超级几何体:在二维三角化中,最后会去除与初始超级三角形相关联的三角形;在三维中,去除与初始四面体相关联的四面体,以得到最终的三角化结果。

  6. 优化与提炼:根据需要,可能会对最终的三角化结构进行进一步的优化和提炼,比如移除太小或形状不佳的三角形,平滑处理等。

Delaunay 三角化因其相对简单和生成高质量网格的能力而广泛应用于计算机图形学和几何建模中。特别是在表面重建领域,它能够有效地从散乱的点集中构建出精确的三维表面。

三、Delaunay三角片的特性

Delaunay三角网是满足delaunay特性的三角剖分,在二维平面上满足两个特性:
(1)最小内角最大化;
(2)最大外接圆最小化;
在三维空间中,对三维点集的剖分又叫做delaunay四面体剖分,由于四面体的内角和不定,所以只满足最大外接球最小化这个特性。

四、实现delaunay算法的分类

生长算法

逐点插入算法

分治算法

基于Bowyer-Watson算法

五、代码

调用scipy的API

pts=np.array([[1, 0, 0],
[1, 0, 1],
[0, 0, 0],
[1, 1, 1],
[0, 1, 0],
[0, 0, 1]])
tri = Delaunay(pts)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.plot_trisurf(pts[:,0], pts[:,1], pts[:,2], triangles=tri.simplices, cmap=plt.cm.Spectral)
plt.show()

调用cgal的API

#include 
#include 
#include 
#include 
typedef CGAL::Exact_predicates_inexact_constructions_kernel            Kernel;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Kernel> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb>                       Tds;
typedef CGAL::Delaunay_triangulation_2<Kernel, Tds>                    Delaunay;
typedef Kernel::Point_2                                                Point;
using namespace std;

int main(vector<vector<float>>& pts){
  vector< pair<Point,unsigned> > points;
  points.push_back( make_pair( Point(-0.0177396,0.0642294), 0 ) );
  points.push_back( make_pair( Point(-0.0177283,0.0627822), 1 ) );
  points.push_back( make_pair( Point(-0.018731 ,0.0627665 ), 2 ) );
  points.push_back( make_pair( Point(-0.0187526,0.0641914), 3 ) );
  points.push_back( make_pair( Point(-0.0147168,0.0628748), 4 ) );
  points.push_back( make_pair( Point(-0.0157188,0.0628375), 5 ) );
  points.push_back( make_pair( Point(-0.0147222,0.0643235), 6 ) );
  points.push_back( make_pair( Point(-0.0157228,0.0642918), 7 ) );
  points.push_back( make_pair( Point(-0.0167333,0.0642714), 8 ) );
  points.push_back( make_pair( Point(-0.0177346,0.065722 ), 9 ) );
  points.push_back( make_pair( Point(-0.0187399,0.0656914), 10 ) );
  points.push_back( make_pair( Point(-0.0177409,0.0671746), 11 ) );
  points.push_back( make_pair( Point(-0.0187525,0.0671388), 12 ) );

  Delaunay triangulation;
  triangulation.insert(points.begin(),points.end());

  for(Delaunay::Finite_faces_iterator fit = triangulation.finite_faces_begin();
      fit != triangulation.finite_faces_end(); ++fit) {

    Delaunay::Face_handle face = fit;
    cout << face->vertex(0)->info()<<" "<< face->vertex(1)->info()<<" "<< face->vertex(2)->info() << endl;
  }
}

六、参考来源

[1] 知乎1
[2] 关于cloudcompare软件里面delaunay三角化的解释
[3] 原理
[4] 获取边表:靠谱:edgeTable、 边表原理

你可能感兴趣的:(表面重建,表面重建)