集合表示
要通过图形学建模表示现实生活中的各个物体,再在计算机上把这些物体呈现出来,就涉及到了几何
一般有两种表示集合的方法:
- 隐式几何表示
- 显示几何表示
隐式几何表示
隐式几何表示是一种用数学关系式来描述几何形状的方法,而不是直接描述其顶点和边界等元素,通常以方程的形式给出,在隐式几何表示法中所有方程的解构成了几何结构
隐式几何通常可以用来表示:
- 代数曲面
- 构造实体几何
- 距离函数
- 水平集
- 分形
而隐式几何表示的优点:
- 容易表述(一个函数就行),对于存储空间来说非常有利
- 判断一个点在几何内/外特别快
- 与光线求交点特别容易
- 对于简单的形体,描述非常准确,不容易出现误差
- 处理变化的拓扑结构非常容易,比如流体模拟
缺点:很难用函数描述一个复杂的模型,复杂的模型只能用显示表示(三角面模型)
代数曲面
代数曲面是通过一组参数方程定义的曲线和表面,可以使用一个方程来表示的几何体
构造实体几何
构造实体几何是通过布尔运算来组合不同的几何体,一些复杂的几何体就可以通过简单几何体的运算来组成
距离函数
距离函数描述了空间中任何一个点到几何体表面的最小距离,一种特殊的距离函数,符号距离函数(Signed Distance Function),以空间中任意一个点作为输入,根据距离函数的返回值可以判断:
- 当距离函数的值大于0,表示点在几何体外部
- 当距离函数的值小于0,表示点在几何体内部
- 当距离函数的值等于0,表示点在几何体表面
在上图这样一个例子中,一个物体从
这时,引入距离函数,对
水平集
但有时对于表面复杂的集合体来说,距离函数计算起来十分困难,因此可以使用一种距离函数的离散形式——水平集的方法来实现和距离函数同样的功能
水平集存储了一系列的距离值,通过线性插值,可以找到数值为
而在三维空间中,水平集可以和纹理联系起来,纹理定义了空间中所有点的属性,如:骨骼的密度为
分形
分形,类似于递归,即局部和整体的形状相似,如下图所示。分形通过迭代函数系统(IFS)来生成。IFS是一种迭代的过程,该过程将函数反复应用于某个起始点或起始数据。这些函数通常是缩放、旋转、平移等操作,同时保持自相似性。
显示几何表示
显示几何表示是一种直接或间接(通过参数映射的方式)来定义点、线、面等元素集合的方法。在显示集合表示中各元素的位置通常由坐标值直接给出,各元素之间的关系通常由数据结构来表示
上图即为一个通过
显示几何表示的优点:很容易、快速得到几何模型
缺点:判断点是否在几何内/外很困难
点云
通过大量密集的点构成了面的思想,来表示空间中复杂的几何模型,点的密度越高,几何体的精度越高,扫描所得到的数据一般为点云的数据形式,而这种形式的表示方式通常会被转换成多边形网格
多边形网格
多边形网格是图形学中最常用的几何表示方法,存储点和多边形(一般为三角形或四边形)的坐标,便于后续做顶点处理
在 3D 建模中,我们经常会用到 .obj
格式的模型文件,其本质上是一个文本文件,记录了顶点、法线、纹理坐标、连接关系,由此构成几何体的形状。如下所示,是一个立方体结构的表示
v
表示顶点vn
表示法线(多了两条是因为建模误差)vt
表示纹理坐标f
表示面,比如f 5/1/1 1/2/1 4/3/1
表示三角形面是由第 5、1、4 个顶点组成,三个点的纹理坐标是第 1、2、3 对应的纹理坐标,面的法线是第 1 条法线。
曲线
曲线在图形学中的应用十分广泛,比如:相机的拍摄路径,物体的移动路径,动画曲线,矢量字体等
贝塞尔曲线
贝塞尔曲线时通过一系列控制点定义的曲线,四个控制点即可定义一条贝塞尔曲线,起始方向沿
德卡斯特里奥算法
德卡斯特里奥给出了贝塞尔曲线的绘制算法
由
- 定义一个时间
,分别在 和 上取 位置的点 - 在第一步所得到的两点连线上再次取
位置的点 - 通过连续的
的取值,即可得到一系列对应的点,也即一条贝塞尔曲线
通过不断的递归操作,可以将更高阶的贝塞尔曲线转为低阶的贝塞尔曲线进行绘制
代数表示
对于上述的算法可以通过代数的表示方法来替代,同样以
由次可以得出
其中
性质
贝塞尔曲线具有一些良好的性质:
- 一定过起点和终点
- 不受仿射变换影响,但受投影变换的影响
- 凸包性质:贝塞尔曲线在所有控制点的凸包范围内
分段贝塞尔曲线
用贝塞尔曲线来绘制一条复杂的曲线时需要更多的控制点,此时控制点的选取极为困难,因此考虑将一条复杂的曲线变为多段贝塞尔曲线相连,可以有效地解决问题
通过将一条曲线划分为多段贝塞尔曲线,每段贝塞尔曲线由四个控制点所控制
当两个贝塞尔曲线连接时,需要满足一定的连续性,通过连接点的
其他曲线表示方式
常见的曲线表示方式还有:样条,B-样条,非均匀有理B-样条(NURBS)
在
曲面
三维空间中,一般用曲面来表示各种模型
贝塞尔曲面
贝塞尔曲面的绘制与贝塞尔曲线的绘制类似,首先找到
曲面处理
在得到了曲面后一般会对曲面进一步处理。一般有三种处理操作:
- 网格细分(Mesh Subdivison)
- 网格简化(Mesh Simplification)
- 网格正则化(Mesh regularization)
网格细分
将一个多边形拆分成多个多边形
Loop细分
Loop细分只适用于三角形面的细分,具体分为两步:
- 将一个三角形拆分成四个三角形
- 通过一定的加权算法更新新产生的顶点和旧顶点的位置
而更新时,各个点的权重与待更新的点的度有关
Catmull-Clark细分
相比对 Loop 细分,Catmull-Clark 细分是一种更加通用的细分方法,适用于各种多边形网格曲面,Catmull-Clark细分中,将度不为4的点称为奇异点
- 对于每一条边取中点
- 对于每一个多边形内部取一点,如重心
- 连接边的中点和面内一点
每进行一次这样的操作后,所有的非四边形都消失了,并引入了和原来非四边形个数相等的奇异点个数
对于新顶点的更新,Catmull-Clark细分中将其分为了两种
对于旧顶点的更新按另外一种方法
实际效果非常不错
网格简化
在一些情况下,如距离摄像机很远的地方,并不需要做到太高的模型精细程度,这个时候就要通过减面的操作来降低操作复杂度,提升性能
网格简化一般采用边坍缩的方式来实现,减少边的数量,更新相关顶点的位置
在选取坍缩点时,引入一个新的概念:二次度量误差,即更新后的点到所有与它有关的边的距离之和,找到一个二次度量误差最小的点,即为需要的坍缩点