二维几何变换(待补)
- 平移
二维观察流水线
C代表coordinate
建模坐标系-> 世界坐标系-> 观察坐标系->设备坐标系
裁剪
点的裁剪
直接判断是否在窗口内部即可
直线段的裁剪
基本思想:对每条直线段p1(x1,y1) p2(x2,y2)分三种情况处理:
(1) 直线段完全可见,“取”之。
(2) 直线段显然不可见,“弃”之。
(3) 直线段既不满足“取”的条件,也不满足“弃”的条件,需要对直线段按交点进行分段,分段后重复上述处理。
编码:对于任一端点(x,y),根据其坐标所在的区域,赋予一个4位的二进制码D3D2D1D0。
编码规则如下:
若x<xL,则D0=1,否则D0=0;
若x>xR,则D1=1,否则D1=0;
若y<yB,则D2=1,否则D2=0;
若y>yT,则D3=1,否则D3=0。
裁剪一条线段时,先求出端点p1和p2的编码code1和code2:
(1)若code1 | code2 = 0,对直线段应取之
(2)若code1 & code2 != 0,对直线段可弃之
(3)若上述两条件均不成立。则需求出直线段与窗口边界的交点。在交点处把线段一分为二,其中必有一段完全在窗口外,可以弃之。再对另一段重复进行上述处理,直到该线段完全被舍弃或者找到位于窗口内的一段线段为止。
(1) 输入直线段的两端点坐标:p1(x1, y1)、p2(x2, y2),以及窗口的四条边界坐标:yT、yB、xL和xR。
(2) 对p1、p2进行编码:点p1的编码为code1,点p2的编码为code2。
(3) 若code1 | code2=0,对直线段应简取之,转(6);
否则,若code1 & code2 != 0,对直线段可简弃之,转(7);当上述两条均不满足时,进行步骤(4)。
(4) 确保p1在窗口外部:若p1在窗口内,则交换p1和p2的坐标值和编码。
(5) 按左、右、上、下的顺序求出直线段与窗口边界的交点,并用该交点的坐标值替换p1的坐标值。也即在交点s处把线段一分为二,并去掉p1s这一段。考虑到p1是窗口外的一点,因此可以去掉p1s, 转(2)
(6) 用直线扫描转换算法绘制当前的直线段p1p2。
(7) 算法结束。
三维观察流水线
观察变换
变换过程:
- 原点到视点的平移变换
- 绕z1轴的旋转变换
- 绕x2轴的旋转变换
-
关于y3O3z3面的反射变换
投影变换
平行投影: 正投影 斜投影
正投影:三视图 && 正轴测图
透视投影
三维实体表示基础
点:最基本的零维几何元素 (x,y,z)
边:一维几何元素 一条边由两个端点表示 折现一般用顶点序列来表示
面:二维几何元素
环:由有向边顺序组成的面的边界
体:三维几何元素,由封闭的表面围成的空间。
几何信息:用来描述物体的位置和大小
拓扑信息:用来描述点,棱边及面片之间的邻接关系,具体表现为棱边及面片的数据结构。
一个有效的实体有如下性质
- 刚性
- 具有封闭的边界
- 内部连通
- 占据有限的空间
- 经过集合运算后仍然是有效的实体
实体模型是最完善的模型定义,它能够表达全部的形状信息,如物体位置、面积、长度、体积、拓扑关联等,同时也定义了物体的并、交、差集合运算和欧拉运算等。
三维实体表示方法
边界表示
通过描述实体的边界来表示实体。
判断实体是否合法: 边界的每条邻边必须要有两个已知坐标的端点。 每条边只能被两个面共享。 每个顶点至少被三个面或三个边共享。
优点:能显式地表示形体边界,绘制时能快速计算法向和光照效果,算法简单。 便于局部几何变换。 便于多个形体做并,交,差运算。 可利用欧拉公式来判断有效正则性。
欧拉公式 V-E+F = 2 V顶点数,E边数,F面数。(对于简单多面体)
非简单多面体 V-E + F- H = 2(C- G) H形体表面的孔数 G 穿透多面体的洞数 C 独立不相连的多面体数
常用的数据结构
class Point
{
int id; //顶点编号,有时可以不要该成员
int x; //横坐标
int y; //纵坐标
}
vector<Point> Points; //存放Point对象的动态数组
class Edge
{
int edge_id; //边的编号,有时可以不要该成员
int BeginPoint;
//为指向Points数组中对应边的起点的元素的索引
int EndPoint;
//为指向Points数组中对应边的终点的元素的索引
int LeftFacet;
//为指向Facets数组中对应此边左侧邻面的元素索引
int RightFacet;
//为指向Facets数组中对应此边右侧邻面的元素索引
}
vector<Edge> Edges; //存放Edge对象的动态数组
class Facet
{
vector<int> vertices; //该面片边界顶点序列数组, // 其元素值为指向Points数组的指针
vector<int> edges; //该面片各边的数组,
// 其元素值为指向Edges数组的指针
}
vector<Facet> Facets;//存放Facet对象的动态数组
翼边数据结构:以边为核心,每条边记录中设置指向其两个顶点,左右两个邻面,上下左右四条邻边的指针。每个顶点的记录都指向以它作为端点的一条表。每个面的记录指向其一条边的指针。
对称数据结构:存放了面→边、边→面、边→点、点→边的4种拓扑关系,每个面记录中设置了指向它所有边的指针,同样,每条边记录中也设置了指向它两个邻面的指针和两个顶点的指针,每个点设置以它为端点的所有边的指针。这种数据结构的空间复杂度为6E,E为实体中的边数。
半边数据结构:一条边被表示成拓扑意义下的方向相反的两条半边。实体由多边形(面)的组合来表示,而多边形由外环及内环组合而成,环又是半边构成的序列,每条半边又由两个顶点构成。
扫描表示
平移扫描:物体沿着某一直线方向平移一段距离
旋转扫描:物体围绕某一轴线旋转一定距离
广义扫描:物体沿着某一空间曲线扫描一定距离
构造实体几何表示
基本思想:将简单实体通过集合运算组合成所需要的物体。
CSG(Constructive Solid Gemetry)
采用单一的建筑块形式的构造实体造型方法,由两个物体的正则几何操作生成新的物体。(并,交,差)
CSG法:集合运算的实现过程用一颗二叉树来描述。
二叉树叶子节点表示体素或者集合变换的参数。
非终端节点表示施加于其子节点上的实体集合运算或几何变换。
根节点表示的就是集合运算的最终结果。
优点: 覆盖域广泛,输入方便,可直观地构造复杂图形。数据结构简单,数据量小,用一颗二叉树即可表示。 形体的有效性可由实体集合运算保证。
缺点:体素很多都是由参数和表面方程表示的,用表面方程和参数表示易于求交点,方便了集合运算,但运算后的中间结果很难用方程和参数表示,后面的集合运算难度较大。解决方案:将中间结果转化为边界表示。
集合运算会破坏原有的点边面的显示拓扑关系。
体素的形状有限。体素不能进行局部变形操作,CSG的表现能力有限制。
空间细分表示法
体素表示法,八叉树表示法
*体素表示法常用于物体的CT或MRI图像的三维重建。体素表示法:实体占有的空间被划分成均匀的小立方体,小立方体构成三维矩阵,小立方体即为体素。用体素表示的空间成为三维位图。