判断三维模型是否是闭合的算法

本文提出了一种优化算法,通过计算三维模型边数与面片数量的关系,来判断模型是否闭合,相较于传统方法显著提高了效率。特别适用于处理包含大量面片的复杂模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于多边形网格的三维模型在我们的工作中是最常见的,这里,我们只针对被多边形面片“离散化”的三维模型。

计算机图形学相关的项目(比如快速成型,逆向工程等等)中,经常的需要判断三维模型是否闭合,最常规的做法就是对每个n边形面片进行判断,如果每个n边形面片都与其他n个m边形面片相邻(m可以等于n,也可以不等于),那么这个三维模型就是闭合的,这样做的时间复杂度是:O(n方);对比较复杂的模型,比如:几万个甚至更多的n边形面片,这个复杂度过大了,会影响系统效率。

这里,提出一个效率比较好的方法,假设三维模型网格的边数为:line_count,组成三维模型的w个n边形面片分别为:polygon1,polygon2,……polygonw;它们的边数依次是:n1,n2,……nw,则假如是闭合的三维模型,就满足:line_count*2=polygon1*n1+polygon2*n2+……+polygonw*nw。否则(line_count*2!=polygon1*n1+polygon2*n2+……+polygonw*nw),就是不闭合的三维模型;使用这个公式,除了line_count,其他变量都为已知,时间复杂度为:O(n*logn)。这是因为:如果三维模型闭合,则每条边必然是两个n边形面片的邻边,我们把邻边看成是两条边,则顺利成章的出来了上面的公式。在模型离散化表示中,三角面片是最常见的,下面我们将以三角面片为例进行阐述,其他的可以类推。

在中国图像图形学报上的一篇“三维散乱点集的曲面三角剖分”上有这样一个公式,也印证了我的想法,看下图:

 

下面呈上简单的代码,代码中使用了红黑树,红黑树相关的内容,详见我的另一篇博文:红黑树的代码实现。这里代码略去:

struct Section
{
	Triangle** tri;
	int tri_count;
};

enum SectionType
{
	SECTION_TYPE_CLOSED, SECTION_TYPE_CONNECTED, SECTION_DETACH, SECTION_TYPE_UNDEFINE
};

//获得三维模型中点的个数
static int get_vertex_count(Triangle ** pTri,int tri_num)
{
	float3* vertex_collection=new float3[tri_num*5];

	int i = 0;

	RB_Tree tree_vertex;

	initial_tree_with_vertex( pTri, tree_vertex, vertex_collection, i );

	for ( int j = 1; j != tri_num; ++j )
	{
		add__tree_with_vertex( pTri, tree_vertex, vertex_collection, i, j );
	}

	delete[] vertex_collection;

	return tree_vertex.size;
}


//获得三维模型中边的数量
static int get_line_count( Triangle** pTri,int tri_num)
{
	float3* line_center_collection = new float3[tri_num*5];

	int i = 0;

	RB_Tree tree_line;

	initial_tree_for_judgeTopological( pTri, tree_line, line_center_collection, i );

	for ( int j = 1; j != tri_num; ++j )
	{
		add__tree_for_judgeTopological( pTri, tree_line, line_center_collection, i, j );
	}

	delete[] line_center_collection;

	return tree_line.size;
}


/// <summary>   
///获得模型的拓扑结构(连通,闭合,分离)
/// </summary>   
/// <param name="sect">三维模型</param>    
/// <returns>模型的拓扑结构(连通,闭合,分离)</returns>  
SectionType get_section_type(Section *sect)
{
	LinkObject object;

	int vertex_count=get_vertex_count(sect->tri,sect->tri_count);

	int line_count=get_line_count(sect->tri,sect->tri_count);

	if(line_count<vertex_count-1)
	{
		return SECTION_DETACH;
	}

	split_STL_model(object,sect->tri,sect->tri_count);

	if(object.m_pEnd!=NULL)
	{
		return SECTION_DETACH;
	}
	else if(line_count * 2 == sect->tri_count * 3 )
	{
		return SECTION_TYPE_CLOSED;
	}
	else if(line_count * 2 > sect->tri_count * 3)
	{
		return SECTION_TYPE_CONNECTED;
	}

	return SECTION_TYPE_UNDEFINE;
}




参考文献:

1,三维散乱点集的曲面三角剖分 张永春,达飞鹏,宋文忠(东南大学自动化研究所)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值