使用CGAL将凹多边形划分为三角网格的方法(人生第一次发博文o(╥﹏╥)o)

使用CGAL进行多边形划分三角形基元,要求保留多边形平面外轮廓特征。
输入:逆时针排序 多边形轮廓点坐标
输出:划分后各三角形顶点索引

对于凸多边形,我们可以直接使用多种三角剖分方法进行三角网格划分,比如约束三角剖分CDT:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <vector>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_tag                               Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag> CDT;
typedef CDT::Point_2                             Point;

struct TriIndex
{
unsigned value[3];
TriIndex () {
			for (unsigned i = 0; i < 3; ++i)
				value[i] = -1;}
TriIndex (unsigned i1, unsigned i2, unsigned i3){
			value[0] = i1;
			value[1] = i2;
			value[2] = i3;}
		
	unsigned &operator[](unsigned i){
return value[i];}	
};typedef std::vector<TriIndex> TriIndices;

unsigned findVertexIndex(Point pt,std::vector<Point> points)
{
    std::vector<Point>::iterator item = std::find(points.begin(), points.end(), pt);
	if (item != points.end())
	{
		unsigned pos = std::distance(points.begin(), item);
		return pos;
}
	return -1;
}
 
TriIndices void GetTriIndices(std::vector<Point> points)
{
   CDT cdt;
   cdt.insert(points.begin(), points.end());

 unsigned vertIndex;
TriIndex triIndex;
TriIndices triIndices;
for (CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it)
{
	 for (unsigned i = 0; i < 3; ++i)
	  {
		point = it->vertex(i)->point();
		vertIndex = findVertexIndex(point, points);
		triIndex[i] = vertIndex;
	  }
       triIndices.push_back(triIndex);
}
  return triIndices;
}

获取所有三角形顶点索引便可以绘制出相应的多边形网格面;然而对于凹多边形会出现差错!!

在这里插入图片描述
怎么办???
解决办法:先进行多边形分割,再划分三角网,具体操作如下:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_conformer_2.h>
#include <CGAL/Partition_traits_2.h>
#include <CGAL/partition_2.h>
#include <list>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Exact_predicates_tag                               Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag> CDT;
typedef CDT::Point_2                             Point;

typedef CGAL::Partition_traits_2<K>                         Traits;
typedef Traits::Polygon_2                                   Polygon2;
typedef std::list<Polygon2>     Polygon_list;

struct TriIndex
{
unsigned value[3];
TriIndex () {
			for (unsigned i = 0; i < 3; ++i)
				value[i] = -1;}
TriIndex (unsigned i1, unsigned i2, unsigned i3){
			value[0] = i1;
			value[1] = i2;
			value[2] = i3;}
		
	unsigned &operator[](unsigned i){
return value[i];}	
};typedef std::vector<TriIndex> TriIndices;

unsigned findVertexIndex(Point pt,std::vector<Point> points)
{
    std::vector<Point>::iterator item = std::find(points.begin(), points.end(), pt);
	if (item != points.end())
	{
		unsigned pos = std::distance(points.begin(), item);
		return pos;
}
	return -1;
}
 


主要改动这里
TriIndices void GetTriIndices(std::vector<Point> points)
{
// 先进行凹多边形划分凸多边形集合
	Polygon_list polys;
	CGAL::approx_convex_partition_2(points.begin(),
points.end(),std::back_inserter(polys));

//对于每个凸多边形
    CDT cdt;
	Polygon2 poly;
unsigned vertIndex;
TriIndex triIndex;
TriIndices triIndices;
	for (Polygon_list::iterator it = polys.begin(); it != polys.end();++it)
	{
		//约束三角剖分
		cdt.clear();
		cdt.insert(it->vertices_begin(), it->vertices_end());

for (CDT::Finite_faces_iterator it = cdt.finite_faces_begin(); it != cdt.finite_faces_end(); ++it)
		{
			for (unsigned i = 0; i < 3; ++i)
			{
				point = it->vertex(i)->point();
				vertIndex = findVertexIndex(point, points);
				triIndex[i] = vertIndex;
			}
triIndices.push_back(triIndex);
		} 
 return triIndices;
}

最终生成我们需要的结果:
在这里插入图片描述

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值