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

来源:互联网 发布:怎么做淘宝商家入驻 编辑:程序博客网 时间:2024/06/02 05:34

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

计算机图形学相关的项目(比如快速成型,逆向工程等等)中,经常的需要判断三维模型是否闭合,最常规的做法就是对每个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,三维散乱点集的曲面三角剖分 张永春,达飞鹏,宋文忠(东南大学自动化研究所)

 

原创粉丝点击