半边数据结构(The_Half-Edge_Data_Structure)
文章转载自:https://blog.csdn.net/lafengxiaoyu/article/details/51524361
介绍
表示多边形网格(polygon mesh)的一个常用方式就是使用共享的顶点列表和面的列表(里面包含面所含的顶点)。这样的表示方法在许多情况下都非常方便和高效,但是在某些特定的领域,反而会效率比较低。
举例来说,网格简化(mesh simplification)通常需要把一条边退化成一个顶点。这个操作需要删除与这条边邻接的面并且更新面中存储的与这条边相关的顶点数据。这种多边形“手术”需要我们了解网格的组成部分的邻接关系,例如面和顶点。虽然我们肯定可以用之前提及的网格表示方法来实现网格简化,但是代价会比较高。许多情况下需要遍历面或者点的列表,或者二者都有。
在一个多边形网格上其他类型的的临近查询包括:
- 哪条边用到了这个点
- 哪条边用到这个点
- 哪个面临近这条边
- 哪条边临近这个面
- 哪个面临近这个面
为了使得这些类型的临近查询更加有效,发展出更加精细的边界表示方案(b-reps),更加明确地建模表示点、边和面,并且也临近信息也相应地储存进去了。
这些表示类型中最常见的其中一种是“翼边数据结构”(winged-edge)。其中每条边包含了指向其两个顶点,两个邻接面的指针以及指向从其终点延伸出去的四条边的指针。这种结构可以让我们在常数时间内判断哪些点与面与该边连接,但是面对其他类型的查询,这种结构会带来更大的开销。
半边(half-edge)数据结构是一种略微复杂的边表示方法(b-reps)并且在其上做之前提到的所有操作都可以在常数时间完成(*)。更优秀的是,即使包含了面、顶点和边的邻接信息,数据结构的大小是固定的(没有使用动态数组)且紧凑的。
这些特性是的半边数据结构成为了许多应用的最佳选择,但是其只能表示流形表面(manifold surfaces),而在某些情况下被证明是不可用的(流形的数学定义指的是曲面上的每一点都有一个小邻域,小邻域有一个圆盘的拓扑结构)。。对于多边形网格来说,这意味着每条边是且只能是两个面的边,T-型接合(t-junctions)和内部多边形(internal polygons)和网格中的空缺时,不能使用半边结构。
(*)更确切地说,每个片段信息的常数时间集中。比如,当查询一个顶点周围所有的临近边时,在临近顶点的边的操作上与数量是线性的,但是每条边是常数时间。
结构
之所以称为半边数据结构,是因为在这个结构中并不会存储网格的边的信息,取而代之的是半边(half-edges)。半边这么叫,就是因为它其实是一条边的一半,等于是把一条边保持长度不变,形式上分为两条半边(因为按照定义边没有宽度或者至少是单位宽度,这就是一个假象划分)。这两条半边组合在一起称为一条边,也就是一条边等于一对半边。半边是有方向的,并且一条边的一对半边有相反的方向。
下图展示了三角形网格的一小部分的半边描述。蓝色是顶点,橙色是半边,其中的箭头表示指针(为了不画得太乱,省略了一些)
可以很清楚地看到围绕一个面的三条边形成了一个环(circular linked list)。这个链表既可以顺时针也可以逆时针,只要在使用中保持一致就好。环中的每半边存储一个指向以其为边的面的指针(图中没有画出来)、指向半边终点的指针(同样没画出来)和指向它的另一条半边(就是合起来组成一条边的那个半边)的指针。在C语言中,结构如下:
struct HE_edge { HE_vert* vert; // vertex at the end of the half-edge HE_edge* pair; // oppositely oriented adjacent half-edge HE_face* face; // face the half-edge borders HE_edge* next; // next half-edge around the face };
在半边数据结构中的点储存着x,y,z的位置和以其为起始点的半边的指针。在任意给定的点上存在超过一条我们可以选择的半边
,但是我们只需要选择其中一条并且是哪一条没关系,在下面的查询方法中我们会看到解释。在C中点数据结构如下
struct HE_vert { float x; float y; float z; HE_edge* edge; // one of the half-edges emantating from the vertex };
对于一个半边数据结构的简单形式,一个面仅仅需要储存一个围绕它的边的指针,在一些特定场合可能要求我们储存比如材质和法向一类的信息。和上面一样,虽然有很多边围绕着面,我们只需要储存其中一条,而无所谓是哪一条。下面是在C中面的数据结构
struct HE_face { HE_edge* edge; // one of the half-edges bordering the face };
邻近查询
关于邻近查询的大多数答案就储存在边、点和面的数据结构里。比如,围绕着半边的面或者点可以轻易地找出
HE_vert* vert1 = edge->vert;
HE_vert* vert2 = edge->pair->vert; HE_face* face1 = edge->face;
HE_face* face2 = edge->pair->face;
稍微复杂一点的例子,找到围绕着面的所有半边。因为围绕着面的所有半边形成了一个环状列表,并且面结构中储存了其中一个半边的指针,因此我们可以
HE_edge* edge = face->edge; do { // do something with edge edge = edge->next; } while (edge != face->edge);
类似地,我们可能对围绕着特定点的边或者是面感兴趣。参照之前的图解,指针组成了围绕点的一个圈,迭代程序类似,如下:
HE_edge* edge = vert->edge; do { // do something with edge, edge->pair or edge->face edge = edge->pair->next; } while (edge != vert->edge);
值得注意的是所有的例子中都没有检查空指针,这是因为流形曲面的限制。为此要求,所有的指针都必须是有效的。
其他邻近关系都可以通过下面的这些例子被迅速找到。
附注
哈佛图形档案网格实验室有一套完整的半边数据结构实现代码,可以参看http://www.cs.deas.harvard.edu/~xgu/mesh/
之前提到半边数据结构在某型情况下不能用。但是翼边数据结构可以。更多的信息可以查看"Computer Graphics: Principles and Practice"
转载于:https://www.cnblogs.com/jeasonliu/p/9098572.html
半边数据结构(The_Half-Edge_Data_Structure)相关推荐
- 三维形体的数据结构(1)半边数据结构
这其实是我学习图形学以来第一次真正接触数据结构的一篇博客,除了之前用markdown写的那篇文章,那个就是入个小门. 为什么我开始接触数据机构,因为在我做第一次细分的时候就遇到了麻烦,比如DOO-SA ...
- DOO-SABIN 细分正方体(2)利用半边数据结构表示(一次和两次细分)
之前做过一次细分,可是效果相当不好.也不是效果不好,就是效率特别低,之后我自学了半边数据结构,这篇博文就要对半边数据结构表示的正方体进行细分,希望可以在这篇博文搞定之后就可以实现对任意的立方体进行细分 ...
- OpenGL glut OFF 读取 + 半边数据结构存储
文件格式: https://people.sc.fsu.edu/~jburkardt/data/off/off.html 第一行:OFF 第二行:顶点数 面数 边数 接下来对于某一个顶点都有一行:x ...
- 半边数据结构【Half Edge】
表示多边形网格的常用方法是共享顶点列表和存储其顶点索引的面列表.这种表示既方便又对于许多目的都是有效的,但是在某些领域它被证明是无效的.Half Edge就是解决网格中邻接元素查询的一种数据结构. 1 ...
- 三维CAD建模——基于半边数据结构的基本欧拉操作建模
三维CAD建模--基于半边数据结构的基本欧拉操作建模(elar, B_REP) (欧拉操作 三维CAD建模课 三维CAD建模 高曙明老师 渲染框架 brep 带洞 带柄 B_REP brep el ...
- 什么是鲜为人知但有用的数据结构?
周围有一些数据结构非常有用,但大多数程序员都不知道. 他们是哪一个? 每个人都知道链接列表,二叉树和哈希,但是例如跳过列表和布隆过滤器 . 我想知道更多不常见的数据结构,但值得了解,因为它们依赖于很棒 ...
- 源码分析学习记录(11)——半边结构
2021SC@SDUSC Dust3D在网格无缝缝合时使用了半边数据结构存储相关数据. 表示多边形网格的一个常用方式就是使用共享的顶点列表和面的列表.这样的表示方法在许多情况下都非常方便和高效,但是在 ...
- 网格半边结构(Half edge mesh)
网格半边结构(Half edge mesh) 1.网格的表示 在计算机图形学上,表达表面网格的数据结构有三种,分别是面列表( List of faces).邻接矩阵(Adjacency matrix) ...
- 绝对不能错过!计算机视觉Polygon Mesh Processing读书笔记——3
几何建模算法的效率和内存消耗在很大程度上取决于基础曲面网格数据结构. 选择网格数据结构需要考虑拓扑和算法方面的考虑: 拓扑要求.数据结构需要表示哪种网格? 我们可以依靠2-manifold网格,还是需 ...
- (二) CGAL库应用:轮廓中轴骨架生成create_interior_straight_skeleton_2()及轮廓的偏置create_offset_polygons_2()
1 先看效果图 这是轮廓中轴的计算,中轴代表的是轮廓的骨架,在人体姿态识别.图像处理中是最基本的元素. 这是轮廓往外偏置一定距离的图示. cgal中实现轮廓中轴骨架生成及进行轮廓的偏置的是create ...
最新文章
- Windows Server基础架构云参考架构:硬件之上的设计
- Elasticsearch分布式一致性原理剖析(一)-节点篇
- Yii CDbCriteria 常用方法
- struts+hibernate 分页
- Leetcode 129. 求根到叶子节点数字之和 解题思路及C++实现
- if函数python_pythonif函数
- 新浪微博爬虫设计(Python版)
- turbo c相关文档
- hdu 2089 不要62【数位dp】
- Craigslist模式在中国如何复制?中国特色的差异化在哪里?,互联网营销
- 使用React构建精简版本掘金(三)
- ECharts实现数据可视化入门教程(超详细)
- Spring 学习记录6 BeanFactory(2)
- 在职读研拓宽视野,社科院与杜兰大学合办金融管理硕士项目为你提供能量
- stc单片机c语言程序头文件(stc12c5a60s2.h,STC12C5A60S2单片机头文件
- 2020年最好用的离线下载网盘,不限速度和空间
- 计量经济学及Stata应用 第五章习题 5.7 使用回归模型进行餐馆选址。数据集Woody3.dta包含33家Woody‘s连锁餐馆的以下变量……
- Contention
- 域名争议纠纷如何解决
- metric_logger小解
热门文章
- mac 安装 mongo 及基本命令
- shell 批量修改文件名字
- Windows 安装 Git,sh.exe 调用 Windows 上的 .sh 格式文件
- 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_01-vuejs研究-vuejs介绍
- 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_5_同步技术的原理...
- Git 问题:SSL certificate problem: self signed certificate
- Aiiage Camp Day3 B Bipartite
- Vuejs2.0学习之二(Render函数,createElement,vm.$slots,函数化组件,模板编译,JSX)...
- 是时候为编程界做点贡献了
- php opcode缓存