C++ CGAL在网格中查找内部点

C++ CGAL在网格中查找内部点,c++,mesh,cgal,triangulation,delaunay,C++,Mesh,Cgal,Triangulation,Delaunay,我试图用它来找到三角形网格内部的点。(即,不在其边界上的点集。对于使用函数CGAL::Side_of_triangle_mesh的3D网格,有一种方法。是否有人可以帮助/建议如何将其修改为2D三角剖分 我的测试代码只创建了两个正方形,一个在另一个里面,然后在原点放置一个种子(以形成一个洞),然后执行2D Delaunay三角剖分。当我使用以下函数调用三角形的边网格类时: Point_2 p = points2D[i]; CGAL::Bounded_side res = inside2D(p);

我试图用它来找到三角形网格内部的点。(即,不在其边界上的点集。对于使用函数CGAL::Side_of_triangle_mesh的3D网格,有一种方法。是否有人可以帮助/建议如何将其修改为2D三角剖分

我的测试代码只创建了两个正方形,一个在另一个里面,然后在原点放置一个种子(以形成一个洞),然后执行2D Delaunay三角剖分。当我使用以下函数调用三角形的边网格类时:

Point_2 p = points2D[i];
CGAL::Bounded_side res = inside2D(p); 
我得到一个错误:

/usr/local/include/CGAL/Side_of_triangle_mesh.h:164:16: Candidate function not viable: no known conversion from 'Point_2' (aka 'Point_2<CGAL::Epick>') to 'const Point' (aka 'const Point_3<CGAL::Epick>') for 1st argument
/usr/local/include/CGAL/Side\u of_triangle\u mesh.h:164:16:候选函数不可行:第一个参数没有从“Point_2”(又名“Point_2”)到“const Point”(又名“const Point_3”)的已知转换
这是否意味着三角形网格的边只适用于三维多面体网格?如果是的话,有人能为二维网格提供一种方法吗

我的测试代码如下:谢谢

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Delaunay_mesh_vertex_base_2.h>
#include <CGAL/Delaunay_mesh_face_base_2.h>
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
#include <CGAL/Side_of_triangle_mesh.h>
#include <vector>
#include <CGAL/Delaunay_mesher_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel     K;
typedef K::Point_2 Point_2;
typedef CGAL::Triangle_2<K> triangle;
typedef CGAL::Delaunay_mesh_vertex_base_2<K>                    Vb;
typedef CGAL::Delaunay_mesh_face_base_2<K>                      Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb>            Tds;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds>      CDT;
typedef CDT::Vertex_handle                                      Vertex_handle;
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT>                Criteria;

int main(int argc, char* argv[])
{
    // Create a vector of the points
    //
    std::vector<Point_2> points2D ;
    points2D.push_back(Point_2(-5.0, -5.0));    // ----------
    points2D.push_back(Point_2( 5.0, -5.0));    // |   OUTER
    points2D.push_back(Point_2( 5.0,  5.0));    // |   SQUARE
    points2D.push_back(Point_2(-5.0,  5.0));    // ----------
    points2D.push_back(Point_2(-2.5, -2.5));    // ----------
    points2D.push_back(Point_2( 2.5, -2.5));    // |   INNER
    points2D.push_back(Point_2( 2.5,  2.5));    // |   SQUARE
    points2D.push_back(Point_2(-2.5,  2.5));    // ----------
    size_t numTestPoints = points2D.size();

    // Create a constrained delaunay triangulation and add the points
    //
    CDT cdt;
    std::vector<Vertex_handle> vhs;
    for (unsigned int i=0; i<numTestPoints; ++i){
        vhs.push_back(cdt.insert(points2D[i]));
    }

    // Creare constraints of the sides of the mesh
    //
    cdt.insert_constraint(vhs[0],vhs[1]);
    cdt.insert_constraint(vhs[1],vhs[2]);
    cdt.insert_constraint(vhs[2],vhs[3]);
    cdt.insert_constraint(vhs[3],vhs[0]);

    cdt.insert_constraint(vhs[4],vhs[5]);
    cdt.insert_constraint(vhs[5],vhs[6]);
    cdt.insert_constraint(vhs[6],vhs[7]);
    cdt.insert_constraint(vhs[7],vhs[4]);

    // Create a seed to make sure the inner square is a hole
    //
    std::list<Point_2> list_of_seeds;
    list_of_seeds.push_back(Point_2(0, 0));

    // Refine the mesh into triangles of max side length '1' and ensuring seeds are 'holes'
    //
    CGAL::refine_Delaunay_mesh_2(cdt, list_of_seeds.begin(), list_of_seeds.end(),
                                 Criteria(0.125, 1),false);


    // Call side_of_triangle_mesh
    //
    CGAL::Side_of_triangle_mesh<CDT, K> inside2D(cdt) ;

    int n_inside = 0;
    int n_boundary = 0;
    for(unsigned int i=0; i<numTestPoints; ++i)
    {
        Point_2 p = points2D[i];
        CGAL::Bounded_side res = inside2D(p);
        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        // NO MATCHING FUNCTION Call

        if (res == CGAL::ON_BOUNDED_SIDE) { ++n_inside; }
        if (res == CGAL::ON_BOUNDARY) { ++n_boundary; }
    }
    std::cerr << "2D results for query size: " << cdt.number_of_vertices() << std::endl;
    std::cerr << "  " << n_inside << " points inside " << std::endl;
    std::cerr << "  " << n_boundary << " points on boundary " << std::endl;

    return 0 ;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
typedef CGAL::精确谓词不精确结构内核K;
typedef K::Point_2 Point_2;
typedef CGAL::Triangle_2 Triangle;
typedef CGAL::Delaunay_网格_顶点_基底_2 Vb;
typedef CGAL::Delaunay_网格_面_底_2 Fb;
typedef CGAL::三角测量数据结构Tds;
typedef CGAL::约束的Delaunay三角剖分CDT;
typedef CDT::顶点句柄顶点句柄;
typedef CGAL::Delaunay_网格尺寸_标准_2标准;
int main(int argc,char*argv[])
{
//创建点的向量
//
std::向量点2d;
点2d.向后推(点2(-5.0,-5.0));//----------
点2d.向后推(点2(5.0,-5.0));/|外部
点2d.向后推(点2(5.0,5.0));/|平方
点2d.向后推(点2(-5.0,5.0));//----------
点2d.向后推(点2(-2.5,-2.5));//----------
点2d.向后推(点2(2.5,-2.5));/|内部
点2d.向后推(点2(2.5,2.5));/|平方
点2d.向后推(点2(-2.5,2.5));//----------
size_t numTestPoints=points2D.size();
//创建受约束的delaunay三角剖分并添加点
//
CDT-CDT;
std::矢量vhs;
对于(unsigned int i=0;i必须使用该函数。它将返回包含查询点的面句柄。
然后,需要使用member函数检查面是否在域中

请注意,如果要执行多个查询,则应首先将所有查询点放在一个容器中,并使用 并使用上一点的位置作为定位函数的第二个参数

以下是如何在边界情况下获取入射面的示例代码:

CDT_2 mesh;

CGAL::Locate_type loc;
int li;

Point_2 query;

Face_handle f =  mesh.locate(query, loc, li);

switch(loc)
{
  case FACE:
    f->is_in_domain();
  break;
  case EDGE:
  {
    bool face_1_in_domain = f->is_in_domain(); // first incident face status
    bool face_2_in_domain = f->neighbor(li)->is_in_domain(); // second incident face status
    break;
  }
  case VERTEX:
  {
    // turn around f->vertex(li)
    Face_handle start = f;
    do{
      bool current_face_in_domain = f->is_in_domain();
      Vertex_handle v = f->vertex(mesh.cw(li));
      f = f->neighbor(mesh.ccw(li));
      li = f->index(v);
    }
    while(f!=current);
    break;
  }
  default:
    // outside of the domain.

}

多亏了@Slorio,我才弄清了这一点。底线是,你不能将CGAL::Side_of_triangle_网格用于2D Delaunay网格。相反,你要做的是循环遍历网格中的所有顶点,并通过查看顶点周围的所有相邻面来测试每个顶点。如果任何面都在域之外,那么顶点或点位于网格的边上

以下是更正后的代码:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Delaunay_mesh_vertex_base_2.h>
#include <CGAL/Delaunay_mesh_face_base_2.h>
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
#include <vector>
#include <CGAL/Delaunay_mesher_2.h>


typedef CGAL::Exact_predicates_inexact_constructions_kernel     K;
typedef K::Point_2                                              Point_2;
typedef CGAL::Delaunay_mesh_vertex_base_2<K>                    Vb;
typedef CGAL::Delaunay_mesh_face_base_2<K>                      Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb>            Tds;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds>      CDT;
typedef CDT::Vertex_handle                                      Vertex_handle;
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT>                Criteria;
typedef CDT::Vertex_iterator                                    Vertex_iterator;
typedef CDT::Vertex                                             Vertex;
typedef CDT::Face                                               Face ;
typedef Face::Face_handle                                       Face_handle ;
typedef CDT::Face_circulator                                    Face_circulator ;


int main(int argc, char* argv[])
{

    // Create a vector of the points
    //
    std::vector<Point_2> points2D ;
    points2D.push_back(Point_2(-5.0, -5.0));    // ----------
    points2D.push_back(Point_2( 5.0, -5.0));    // |   OUTER
    points2D.push_back(Point_2( 5.0,  5.0));    // |   SQUARE
    points2D.push_back(Point_2(-5.0,  5.0));    // ----------
    points2D.push_back(Point_2(-2.5, -2.5));    // ----------
    points2D.push_back(Point_2( 2.5, -2.5));    // |   INNER
    points2D.push_back(Point_2( 2.5,  2.5));    // |   SQUARE
    points2D.push_back(Point_2(-2.5,  2.5));    // ----------
    size_t numTestPoints = points2D.size();

    // Create a constrained delaunay triangulation and add the points
    //
    CDT cdt;
    std::vector<Vertex_handle> vhs;
    for (unsigned int i=0; i<numTestPoints; ++i){
        vhs.push_back(cdt.insert(points2D[i]));
    }

    // Creare constraints of the sides of the mesh
    //
    cdt.insert_constraint(vhs[0],vhs[1]);
    cdt.insert_constraint(vhs[1],vhs[2]);
    cdt.insert_constraint(vhs[2],vhs[3]);
    cdt.insert_constraint(vhs[3],vhs[0]);

    cdt.insert_constraint(vhs[4],vhs[5]);
    cdt.insert_constraint(vhs[5],vhs[6]);
    cdt.insert_constraint(vhs[6],vhs[7]);
    cdt.insert_constraint(vhs[7],vhs[4]);

    // Create a seed to make sure the inner square is a hole
    //
    std::list<Point_2> list_of_seeds;
    list_of_seeds.push_back(Point_2(0, 0));

    // Refine the mesh into triangles of max side length '1' and ensuring seeds are 'holes'
    //
    CGAL::refine_Delaunay_mesh_2(cdt, list_of_seeds.begin(), list_of_seeds.end(),
                                 Criteria(0.125, 1.5),false);

    // The mesh is now created. The next bit swings around each vertex point checking that
    // all faces around it are in the domain. If any are not then the vertex is on the
    // edge of the mesh.
    // thanks to @sloriot for this
    //

    Vertex v ;
    std::vector<Point_2> interior_points ;
    std::vector<Point_2> boundary_points ;
    CDT::Locate_type loc = CDT::Locate_type::VERTEX ;
    int li;

    Vertex_iterator vit = cdt.vertices_begin(), beyond = cdt.vertices_end() ;
    while (vit != beyond) {
        v = *vit ;
        Point_2 query = vit->point();
        Face_handle f =  cdt.locate(query, loc, li);

        bool current_face_in_domain ;
        Face_handle start = f ;
        do {
            current_face_in_domain = f->is_in_domain() ;
            Vertex_handle vh = f->vertex(li);
            f = f->neighbor(cdt.ccw(li));
            li = f->index(vh) ;
        }
        while(current_face_in_domain && f != start) ;

        if (f == start) {
            interior_points.push_back(query) ;
        }else{
            boundary_points.push_back(query) ;
        }
        ++vit ;
    }

    printf("Boundary points:\n");
    for(auto p = boundary_points.begin(); p != boundary_points.end(); ++p){
        printf("%f,%f\n",p->x(), p->y()) ;
    }

    printf("interior points:\n");
    for(auto p = interior_points.begin(); p != interior_points.end(); ++p){
        printf("%f,%f\n",p->x(), p->y()) ;
    }

    return 0 ;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
typedef CGAL::精确谓词不精确结构内核K;
typedef K::Point_2 Point_2;
typedef CGAL::Delaunay_网格_顶点_基底_2 Vb;
typedef CGAL::Delaunay_网格_面_底_2 Fb;
typedef CGAL::三角测量数据结构Tds;
typedef CGAL::约束的Delaunay三角剖分CDT;
typedef CDT::顶点句柄顶点句柄;
typedef CGAL::Delaunay_网格尺寸_标准_2标准;
typedef CDT::顶点迭代器顶点迭代器;
typedef-CDT::顶点;
typedef-CDT::正面;
typedef Face::Face_handle Face_handle;
typedef CDT::面部循环器面部循环器;
int main(int argc,char*argv[])
{
//创建点的向量
//
std::向量点2d;
点2d.向后推(点2(-5.0,-5.0));//----------
点2d.向后推(点2(5.0,-5.0));/|外部
点2d.向后推(点2(5.0,5.0));/|平方
点2d.向后推(点2(-5.0,5.0));//----------
点2d.向后推(点2(-2.5,-2.5));//----------
点2d.向后推(点2(2.5,-2.5));/|内部
点2d.向后推(点2(2.5,2.5));/|平方
点2d.向后推(点2(-2.5,2.5));//----------
size_t numTestPoints=points2D.size();
//创建受约束的delaunay三角剖分并添加点
//
CDT-CDT;
std::矢量vhs;
for(unsigned int i=0;ipoint();
面_手柄f=cdt.locate(查询、定位、li);
bool当前面在域中;
面_手柄开始=f;
做{
当前_面_in_domain=f->is_in_domain();
顶点\手柄vh=f->顶点(li);
f=f->邻居(cdt.ccw(li));
li=f->index(vh);
}
while(域中的当前面&&f!=开始);
如果(f==开始){
内部点。推回(查询);
}否则{
边界点。推回(查询);
}
++维生素T;
}
printf(“边界点:\n”);
对于(自动p=边界点。开始();p!=边界点。结束();++p){
printf(“%f,%f\n”,p->x(),p->y());
}
printf(“内部点:\n”);
对于(自动p=内部_点。开始();p!=内部_点。结束();++p){
printf(“%f,%f\n”,p->x(),p->y());
}
返回0;
}
当您运行它时,您应该得到如下信息: