【问题标题】:How do I iterate over faces in CGAL如何在 CGAL 中迭代人脸
【发布时间】:2011-01-05 06:50:13
【问题描述】:

我正在尝试使用 CGAL 进行一些 Delaunay 三角测量。我使用其中一个 CGAL 样本来计算包含高度字段属性的三角剖分。

我遇到的问题是我不知道如何得到三角测量结果。我想出了如何获得 face_iterator,但我不知道从那里做什么。我希望得到的是每个三角形上 3 个点的点数组的索引。

我在浏览所有嵌套模板时遇到问题:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_euclidean_traits_xy_3<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;
typedef K::Point_3 Point;

int main()
{
    //initialize the points with some trivial data
    std::vector<Point> pts;
    pts.push_back(Point(1., 2., 3.));
    pts.push_back(Point(2., 2., 3.));
    pts.push_back(Point(1., 3., 3.));
    pts.push_back(Point(4., 2., 3.));    

    //create a delaunay triangulation
    Delaunay dt;
    dt.insert(pts.begin(), pts.end());

    //iterate through the faces
    Delaunay::Finite_faces_iterator it;
    for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
    {
        //What do I do here??
    }

    return 0;
}

【问题讨论】:

  • it.something ... 代码完成有帮助吗?
  • Visual Studio 2008 无法在此代码上执行完整的代码 :(
  • 突出显示 Delaunay::Finite_faces_iterator 并转到定义。跟踪 .h 文件并查看可用的功能。会的。
  • 您的代码的第一个问题是您使用 Delaunay_triangulation_2 而不是 Delaunay_triangulation_3
  • ...如果您使用 Delaunay_triangulation_2...则使用 2D 点...

标签: c++ computational-geometry triangulation cgal delaunay


【解决方案1】:

您可以使用Delaunay::triangle 将面(迭代器)转换为对应的三角形。这是在 CGAL 3.8 下测试的:

// points.cin contains point pairs, e.g.,
// 3 5 
// 0 0
// 1 9
// ...
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <fstream>

typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2<K> Delaunay;
typedef K::Point_2   Point;

int main()
{
  std::ifstream in("points.cin");
  std::istream_iterator<Point> begin(in);
  std::istream_iterator<Point> end;

  Delaunay dt;
  dt.insert(begin, end);

  Delaunay::Finite_faces_iterator it;
  for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
  {
    std::cout << dt.triangle(it) << std::endl;
  }

  return 0;
}

【讨论】:

    【解决方案2】:

    可以使用 dt.triangle(it)[idx] 访问三角形的顶点,其中 it 是一个面迭代器,idx 是顶点编号 (0, 1 或 2)。在下面的示例中,顶点是 Point_2 对象,可以使用 x() 和 y() 方法访问其笛卡尔坐标。

    #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
    #include <CGAL/Triangulation_euclidean_traits_2.h>
    #include <CGAL/Delaunay_triangulation_2.h>
    
    typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
    typedef CGAL::Triangulation_euclidean_traits_2<K> Gt;
    typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;
    
    typedef K::Point_2 Point_2;
    typedef std::vector<Point_2> Points;
    
    int main()
    {
        Points points;
        points.push_back(Point_2(0,0));
        points.push_back(Point_2(0,7));
        points.push_back(Point_2(7,0));
        points.push_back(Point_2(7,7));
    
        Delaunay dt(points.begin(), points.end());
    
        // Print Cartesian coordinates of vertices of triangles in 2D Delaunay triangulation
        for (Delaunay::Finite_faces_iterator it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
        {
            std::cout << " " << dt.triangle(it)[0].x() << " " << dt.triangle(it)[0].y() << " ";
            std::cout << " " << dt.triangle(it)[1].x() << " " << dt.triangle(it)[1].y() << " ";
            std::cout << " " << dt.triangle(it)[2].x() << " " << dt.triangle(it)[2].y() << " ";
            std::cout << std::endl << "-------------------" << std::endl;
        }
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      这是来自 Google 的示例。 Finite_faces_iterator 是类型定义的。

        Interval_skip_list isl;
        for(Finite_faces_iterator fh = dt.finite_faces_begin();
            fh != dt.finite_faces_end();
            ++fh){
          isl.insert(Interval(fh));
        }
        std::list<Interval> level;
        isl.find_intervals(50, std::back_inserter(level));
        for(std::list<Interval>::iterator it = level.begin();
            it != level.end();
            ++it){
          std::cout << dt.triangle(it->face_handle()) << std::endl;
        }
      

      这不会做你想做的事,而是给你一个例子,说明可以用迭代器做什么。

      【讨论】:

      • 迭代器本身就是 stl 迭代器。问题是我无法弄清楚迭代器指向什么(大概是一张脸或刻面之类的东西)
      【解决方案4】:

      如果您想要一个真正扩展的示例来说明如何完全按照您的意愿行事,请从此处查看 X-Plane 风景工具的源代码:http://scenery.x-plane.com/code.php

      通过扩展示例,我的意思是几十万行,但几乎所有 CGAL 都可以使用 Delaunay 三角剖分和扩展属性。

      【讨论】:

        【解决方案5】:

        我刚刚遇到了一个类似的问题,我做了很多研究(主要是因为我对 C++ 没有任何了解)。我希望能够通过它的顶点整数表示来打印三角形。这是它的外观:

        #include <CGAL/Surface_mesh_default_triangulation_3.h>
        #include <CGAL/Complex_2_in_triangulation_3.h>
        #include <CGAL/make_surface_mesh.h>
        #include <CGAL/Implicit_surface_3.h>
        
        // This is the file where you can look for an example of iterating, geting basic vertex positions, outputing triangles
        // #include <CGAL/IO/Complex_2_in_triangulation_3_file_writer.h>
        
        // default triangulation for Surface_mesher
        typedef CGAL::Surface_mesh_default_triangulation_3 Tr;
        
        // c2t3
        typedef CGAL::Complex_2_in_triangulation_3<Tr> C2t3;
        
        typedef Tr::Geom_traits GT;
        typedef GT::Sphere_3 Sphere_3;
        typedef GT::Point_3 Point_3;
        typedef GT::FT FT;
        
        typedef FT (*Function)(Point_3);
        
        typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;
        
        // This already have been defined
        //typedef typename C2t3::Triangulation Tr;
        typedef typename Tr::Vertex_handle Vertex_handle;
        typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
        typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;
        
        typedef typename Tr::Point Point;
        
        
        FT sphere_function (Point_3 p) {
          const FT x = p.x();
          const FT y = p.y();
          const FT z = p.z();
        
          //const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
          const FT a = 2;
          const FT b = 1;
          const FT c = 1.5;
          return x*x/a/a + y*y/b/b + z*z/c/c -1;
        }
        
        int main() {
          Tr tr;            // 3D-Delaunay triangulation
          C2t3 c2t3 (tr);   // 2D-complex in 3D-Delaunay triangulation
        
          // defining the surface
          Surface_3 surface(sphere_function,             // pointer to function
                            Sphere_3(CGAL::ORIGIN, 2.)); // bounding sphere
          // Note that "2." above is the *squared* radius of the bounding sphere!
        
          // defining meshing criteria
          CGAL::Surface_mesh_default_criteria_3<Tr> criteria(30.,  // angular bound
                                                             0.1,  // radius bound
                                                             0.1); // distance bound
          // meshing surface
          CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());
        
          std::cout << "Final number of points: " << tr.number_of_vertices() << "\n";
        
          // Here should be the main code
        
          Tr& tr2 = c2t3.triangulation();
        
          std::map<Vertex_handle, int> V;
          int inum = 0;
          Finite_vertices_iterator vit = tr2.finite_vertices_begin();
          while(vit != tr2.finite_vertices_end()) {
        
            // making an integer representation of vertex pointers
            V[vit] = inum++;
        
            // obtaining vertex positions from vertex pointer vit
            Point p = static_cast<Point>(vit->point());
            std::cout << p.x() << " " << p.y() << " " << p.z() << std::endl;
        
            ++vit;
          }
        
          Finite_facets_iterator fit = tr2.finite_facets_begin();
        
          while (fit != tr2.finite_facets_end()) {
        
            typename Tr::Cell_handle cell = fit->first;
            const int& index = fit->second;
        
            int index1 = V[cell->vertex(tr.vertex_triple_index(index, 0))];
            int index2 = V[cell->vertex(tr.vertex_triple_index(index, 1))];
            int index3 = V[cell->vertex(tr.vertex_triple_index(index, 2))];
        
            std::cout << index1 << " " << index2 << " " << index3 << std::endl;
            ++fit;
          }
        
        }
        

        编译它(如果mesh_implicit_function 是源文件、目标文件和可执行文件):

        c++   -DCGAL_USE_GMP -DCGAL_USE_MPFR -DCGAL_USE_ZLIB -frounding-math -o mesh_an_implicit_function.cpp.o -c mesh_an_implicit_function.cpp
        c++ mesh_an_implicit_function.cpp.o  -o mesh_an_implicit_function -lmpfr -lgmp -lCGAL -lboost_thread
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-06-17
          • 1970-01-01
          • 1970-01-01
          • 2013-02-10
          • 2012-07-18
          • 2020-06-03
          • 2020-11-02
          相关资源
          最近更新 更多