Создание трехмерных альфа-форм в CGAL и визуализация

Я новый пользователь CGAL с базовым опытом работы с C ++, пытаюсь найти трехмерные альфа-формы набора точек. Я использую 2ex_alpha_shapes

    #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
    #include <CGAL/Delaunay_triangulation_3.h>
    #include <CGAL/Alpha_shape_3.h>

    #include <iostream>
    #include <fstream>
    #include <list>
    #include <cassert>

    typedef CGAL::Exact_predicates_inexact_constructions_kernel Gt;

    typedef CGAL::Alpha_shape_vertex_base_3<Gt>          Vb;
    typedef CGAL::Alpha_shape_cell_base_3<Gt>            Fb;
    typedef CGAL::Triangulation_data_structure_3<Vb,Fb>  Tds;
    typedef CGAL::Delaunay_triangulation_3<Gt,Tds>       Triangulation_3;
    typedef CGAL::Alpha_shape_3<Triangulation_3>         Alpha_shape_3;

    typedef Gt::Point_3                                  Point;
    typedef Alpha_shape_3::Alpha_iterator               Alpha_iterator;

    using namespace std;

    int main()
    {
      std::list<Point> lp;

      //read input
      std::ifstream is("./data/finalwater4.dat");
      int n;
      is >> n;
      std::cout << "Reading " << n << " points " << std::endl;
      Point p;
      for( ; n>0 ; n--)    {
        is >> p;
        lp.push_back(p);
      }

      // compute alpha shape
    //  Alpha_shape_3 as(lp.begin(),lp.end());
      Alpha_shape_3 as(lp.begin(),lp.end(),0.001, Alpha_shape_3::GENERAL);

      // find optimal alpha value
      Alpha_iterator opt = as.find_optimal_alpha(1);
      std::cout << "Optimal alpha value to get one connected component is "
            <<  *opt    << std::endl;
      as.set_alpha(*opt);
      assert(as.number_of_solid_components() == 1);

      /// the rest of the code, prepares the output to be written into a file

      /// collect all regular facets (fetch regular facets from as and inserts in facets)
      std::vector<Alpha_shape_3::Facet> facets;
      as.get_alpha_shape_facets(std::back_inserter(facets), Alpha_shape_3::REGULAR);

      std::stringstream pts;
      std::stringstream ind;

      std::size_t nbf=facets.size();
      for (std::size_t i=0;i<nbf;++i)
      { 
        //To have a consistent orientation of the facet, always consider an exterior cell
        if ( as.classify( facets[i].first )!=Alpha_shape_3::EXTERIOR )
          facets[i]=as.mirror_facet( facets[i] );
        CGAL_assertion(  as.classify( facets[i].first )==Alpha_shape_3::EXTERIOR  );

        int indices[3]={
          (facets[i].second+1)%4,
          (facets[i].second+2)%4,
          (facets[i].second+3)%4,
        };

        /// according to the encoding of vertex indices, this is needed to get
        /// a consistent orienation
        if ( facets[i].second%2==0 ) std::swap(indices[0], indices[1]);


        pts << 
        facets[i].first->vertex(indices[0])->point() << "\n" <<
        facets[i].first->vertex(indices[1])->point() << "\n" <<
        facets[i].first->vertex(indices[2])->point() << "\n"; 
        ind << 3*i+1 << " " << 3*i+2 << " " << 3*i+3 << "\n";
      }

      ofstream myfile;
      myfile.open ("output.dat");
      myfile << "variables = x, y, z\n";
      myfile << "zone n="<< 3*nbf << " , e=" << nbf << " , f=fepoint, et=triangle\n";
      myfile << pts.str();
      myfile << ind.str();
      myfile.close();

      return 0;
    }
8cpp-example.html" rel="nofollow noreferrer">ex_alpha_shapes пример кода, а затем используя инструкции в сохранении сетки поверхности альфа-формы CGAL для визуализации результатов. Кажется, все работает правильно, но когда я пытаюсь изменить значение альфы, заменив

    Alpha_shape_3 as(lp.begin(),lp.end());

с участием

    Alpha_shape_3 as(lp.begin(),lp.end(),1, Alpha_shape_3::GENERAL);

предполагая, что третья переменная является значением альфа (= 1), и меняя это значение каждый раз, результаты не меняются.

В частности, в моем наборе частиц некоторые отделены от большинства, и я хотел бы представить их отдельными объемами (аналогично Рисунок 41.1) с использованием вогнутой оболочки или альфа-форм. В настоящее время я получаю (используя Tecplot для визуализации): введите описание изображения здесьи, как видите, отдельные частицы связаны с другими частицами. Я также прикрепляю свой код в конце. Буду признателен за любую помощь в этом вопросе.

    #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
    #include <CGAL/Delaunay_triangulation_3.h>
    #include <CGAL/Alpha_shape_3.h>

    #include <iostream>
    #include <fstream>
    #include <list>
    #include <cassert>

    typedef CGAL::Exact_predicates_inexact_constructions_kernel Gt;

    typedef CGAL::Alpha_shape_vertex_base_3<Gt>          Vb;
    typedef CGAL::Alpha_shape_cell_base_3<Gt>            Fb;
    typedef CGAL::Triangulation_data_structure_3<Vb,Fb>  Tds;
    typedef CGAL::Delaunay_triangulation_3<Gt,Tds>       Triangulation_3;
    typedef CGAL::Alpha_shape_3<Triangulation_3>         Alpha_shape_3;

    typedef Gt::Point_3                                  Point;
    typedef Alpha_shape_3::Alpha_iterator               Alpha_iterator;

    using namespace std;

    int main()
    {
      std::list<Point> lp;

      //read input
      std::ifstream is("./data/finalwater4.dat");
      int n;
      is >> n;
      std::cout << "Reading " << n << " points " << std::endl;
      Point p;
      for( ; n>0 ; n--)    {
        is >> p;
        lp.push_back(p);
      }

      // compute alpha shape
    //  Alpha_shape_3 as(lp.begin(),lp.end());
      Alpha_shape_3 as(lp.begin(),lp.end(),0.001, Alpha_shape_3::GENERAL);

      // find optimal alpha value
      Alpha_iterator opt = as.find_optimal_alpha(1);
      std::cout << "Optimal alpha value to get one connected component is "
            <<  *opt    << std::endl;
      as.set_alpha(*opt);
      assert(as.number_of_solid_components() == 1);

      /// the rest of the code, prepares the output to be written into a file

      /// collect all regular facets (fetch regular facets from as and inserts in facets)
      std::vector<Alpha_shape_3::Facet> facets;
      as.get_alpha_shape_facets(std::back_inserter(facets), Alpha_shape_3::REGULAR);

      std::stringstream pts;
      std::stringstream ind;

      std::size_t nbf=facets.size();
      for (std::size_t i=0;i<nbf;++i)
      { 
        //To have a consistent orientation of the facet, always consider an exterior cell
        if ( as.classify( facets[i].first )!=Alpha_shape_3::EXTERIOR )
          facets[i]=as.mirror_facet( facets[i] );
        CGAL_assertion(  as.classify( facets[i].first )==Alpha_shape_3::EXTERIOR  );

        int indices[3]={
          (facets[i].second+1)%4,
          (facets[i].second+2)%4,
          (facets[i].second+3)%4,
        };

        /// according to the encoding of vertex indices, this is needed to get
        /// a consistent orienation
        if ( facets[i].second%2==0 ) std::swap(indices[0], indices[1]);


        pts << 
        facets[i].first->vertex(indices[0])->point() << "\n" <<
        facets[i].first->vertex(indices[1])->point() << "\n" <<
        facets[i].first->vertex(indices[2])->point() << "\n"; 
        ind << 3*i+1 << " " << 3*i+2 << " " << 3*i+3 << "\n";
      }

      ofstream myfile;
      myfile.open ("output.dat");
      myfile << "variables = x, y, z\n";
      myfile << "zone n="<< 3*nbf << " , e=" << nbf << " , f=fepoint, et=triangle\n";
      myfile << pts.str();
      myfile << ind.str();
      myfile.close();

      return 0;
    }

person Vahid    schedule 10.07.2014    source источник


Ответы (1)


Если вы хотите отфильтровать вещи, вам нужно взять альфа-форму со значением меньше, чем то, которое возвращает as.find_optimal_alpha (1). Я предлагаю запустить демонстрацию альфа-формы, в которой есть ползунок, который будет отображать, как выглядит альфа-форма, в зависимости от значения альфа. Входной файл должен иметь расширение .pts и содержать количество точек, за которыми следуют координаты точек.

person sloriot    schedule 10.07.2014
comment
Большое спасибо за ваш ответ. Я только что удалил раздел поиска оптимального альфа-значения, и теперь он работает :) - person Vahid; 11.07.2014