图形学日记(一)光栅图形学

本文主要是概念的总结,并不会讲述具体的算法,如需查看详细内容,请点击相关博客。

1、基础概念:

光栅化(图形的扫描转换):确定最佳逼近图形的像素集合,并用指定属性写像素的过程。
一维图形的表示:在不考虑线宽时,可以直接使用一个像素宽的直线、曲线来显示图形。
二维图形的表示:必须区域填充(确定区域对应的像素集,并使用指定的属性与图案显示
之)。
裁剪:确定一个图形的哪些部分在窗口内必须显示;哪些部分在窗口之外不该显示的过程。
走样:因为像素逼近误差,导致所画图形产生畸变(台阶、锯齿)的现象。
反走样:用于减少或消除走样的技术。
隐藏部分:当不透光的物体阻挡了来自某些物体部分的光线,使其无法到达观察者时的这些
不透明物体。
消隐:由于隐藏部分是不可见的,如不删除隐藏的线或面,就可能发生对图形的错误理解。因此必须将隐藏部分从图中删除,而这一需求便是消隐。

2、直线段的扫描转换算法

相关概念:

当有过端点P0(x0,y0),P1(x1,y1)的直线。
该直线的斜截式:y=kx+b;k=(y1-y0)/(x1-x0)。
该直线的一般式:ax+by+c=0;a=y0-y1,b=x1-x0,c=x0y1-y0x1。

DDA算法:

基本思想:先由x轴值稳步增加1,然后根据k(斜率)计算y轴值,使用四舍五入的方式确定像素点,如此循环,直到画完。

中点画线法:

基本思想:先由x轴值稳步增加1,然后根据ax+by+c=0的直线方程来获取线的y轴值,如果y轴值处于当前像素块中的0.5之上,就选择右上方坐标,否则选择正右方坐标。

Bersenham算法:

基本思想:算是上面两种方法的结合改进版,先由x轴值稳步增加1,然后根据k(斜率)获取线的y轴值,然后根据一个误差项符号决定下一个像素取正右方坐标还是右上方坐标。

计算机图形学——直线扫描转换(基本光栅图形算法)
计算机图形学 学习笔记(一):概述,直线扫描转换算法:DDA,中点画线算法,Bresenham算法

3、圆弧的扫描转换算法

相关概念:

八对称性:若已知圆弧上的一点,即可得到4条对称轴与圆弧相交的其他七个点。因此只需
扫描转换出八分之一的圆弧,即可用八对称性求出整个圆弧的像素集。

中点画圆算法:

基本思想:跟中点画线法的思想基本一致,不同之处在于构造函数改为了x^2+y^2-R^2=0;
即先由x轴值稳步增加1,然后根据x^2+y^2-R^2=0来获取圆弧的y轴值,如果y轴值处于当前像素块中的0.5之上,就选择右上方坐标,否则选择正右方坐标。

计算机图形学:中点画圆算法

4、多边形的扫描转换和区域填充

4.1、多边形的扫描转换
相关概念:

活性边:与当前扫描线相交的边称为活性边。
活性边表:把活性边按与扫描线交点x坐标递增的顺序存放在一个链表中,这个链表就是活性表。
新边表:为了方便活性边表建立和更新而建立的一个纵向链表,长度为多边形所占有的最大扫描线数,链表的每个结点称为吊桶,对应多边形覆盖的每一条扫描线,存放着与该扫描线第一次相交的多边形边。

多边形的扫描线算法:

基本思想:从y轴上发射一条条扫描线划过多边形,扫描线经过
多边形内部的像素点就上填充色,在多边形之外的就上背景色。
主要实现方式:通过活性边表求扫描边与多边形边的交点。

多边形的边界标志算法:

基本思想:先使用直线扫描转换将多边形每个边给绘制出来,然后用扫描线算法进行填充。
可以理解为一个人如果让你画一个多边形,你肯定是先拿着多边形顶点去连线,然后在涂颜色。而直线扫描转换就是你在连线,扫描线算法就是你在涂颜色。

4.2、多边形的区域填充
相关概念:

区域:已经表示为点阵形式的填充图形。
内点表示:区域内的所有像素着同一颜色。
边界表示:区域的边界点着同一颜色。
区域填充:先将区域中的一点赋予指定的颜色,然后将该颜色扩展至整个区域的过程。
四连通区域:从区域上一点出发,可通过上下左右4个方向移动的组合,在不越出区域的前提下,到达区域内的任意像素。
八连通区域:从区域上一点出发,可通过上、下、左、右、左上、右上、左下、右下等八个方向移动的组合,在不越出区域的前提下,到达区域内的任意像素。

区域填充的递归算法(种子填充算法):

基本思想:假设在多边形内的一个像素点已知,由此出发利用连通性来找到区域内的所有像素。(八连通的更加全面)

区域填充的扫描线算法:

基本思想:在给定一个种子点之后,就先将该种子点所在扫描线与多边形重叠部分的像素进行填充,然后再找出与该扫描线上、下相邻的两条扫描线,然后再填充,再找相邻,如此循环,直至填充完成。

多边性的扫描转换
计算机图形学——区域填充算法(基本光栅图形算法)

5、字符

常用的字符有两种:ASCII码和汉字编码。标识方式为,采用字节的最高位进行表示,
最高位为0表示ASCII码,最高位为1表示汉字编码。
点阵字符:每个字符使用一个位图表示,其中字位为1则着字符颜色,为0则着背景色。
矢量字符:每个字符使用笔画信息和其对应的端点信息。就好比一笔一笔的写出来的一样。
字符的主要属性包括:字体、字高、字宽因子、字倾斜角、对齐、字色、写方式等。

6、裁剪

相关概念:

裁剪:确定一个图形的哪些部分在窗口内必须显示;哪些部分在窗口之外不该显示的过程。
最简单的裁剪方法就是把各种图形扫描转换为点之后,再判断各点是否在窗口内。
入边:直线由窗口外向窗口内移动时和窗口边界相交的边。
出边:直线由窗口内向窗口外移动时和窗口边界相交的边。

6.1、直线段裁剪
Cohen-Sutherland算法

基本思想:线段全在窗口外就抛弃,全在窗口内则保留。
如果线段只有部分在窗口内,则查找交点,分成两段,不在窗口内的一段抛弃。
重复分段操作行为,直到剩下的线段全在窗口内,则保留。
实现方式:先把窗口的四条边延长,得到9个区域,然后赋予每个区域四位编码,编码的方式为在窗口内的位为0,不在窗口内的位为1. 根据线段的两个端点来获取其所在的区域的编码,全部为0则保留,按位与后不为0(说明完全在窗口外)则抛弃。如果都不是的话,就求交点分割线段。求交点的方式为(按顺序检测端点的编码值不为0时,即与对应的窗口边界求交)。

中点分割裁剪算法

与Cohen-Sutherland算法基本一致,不同的地方在于求交点的方式。
比如:有线段的两个端点p0和p1,p0和p1只有中间部分的线段在窗口中。
于是便求出p0p1的中点,只要p0pm不是显然不可见的,并且p0p1在窗口中有可见部分,
则距离p0最近的可见点一定在p0pm上,于是使用p0pm代替p0p1,否则使用pmp1代替p0p1。
然后取中点求线段。几次重复之后,中点与离p0近的可见点的误差就越来越小,
有点类似牛顿逼近法。离p1最近的可见点也可以通过这样的方式求出。

梁友栋-Barskey裁剪算法
这个有点难。

基本思想:
1、先通过直线的参数方程来确定直线。
将某个点在线段上的位置通过增量乘以u的方式来表示,个人理解增量其实就是线段的长度,
u则是用来控制 点在线段上与起始点间的距离,在线段长度上的占比(0-1)。
2、将窗口的四条边延伸出去,与线段进行相交,得到四个u值,加上起始的u=0、u=1,
求出与 非延伸边 的交点的u值,进行裁剪。
(之所以要01,是因为线段为了求交点,也延伸了,但有可能起点和终点本身就在窗口内,
并不需要对应的交点。)
注:入边和出边的概念在这里有应用,因为梁将线段看为有方向的。
具体的求解过程,笔者就不讲了,也讲不来。自己去看下面的博客。

计算机图形学——裁剪
计算机图形学——梁友栋-Barsky算法
6.2、多边形的裁剪
Sutherland-Hodgeman算法

基本思想:使用窗口的四条边作为裁剪线,裁剪多边形。
实现:由裁剪线将平面分为可见一侧和不可见一侧。依序考虑多边形的各条边的两个端点。
大致可以分为以下几种情况:
(1)两个端点均在可见一侧,则保留两个端点。
(2)两个端点均在不可见一侧,则抛弃两个端点。
(3)两个端点有一个在可见一侧,一个在不可见一侧,则保留可见一侧的线段,
    即保留可见一侧的端点和线段与裁剪线的交点。

最后将这些得到的端点连接起来即可得到可以显示的多边形。
多边形裁剪|Sutherland-Hodgman
6.3、字符串裁剪

字符串裁剪可分为三个精度进行:串精度、字符精度、笔画(像素)精度。
串精度:包围字符串的外接矩形框,没能全部在窗口内,则整个字符串都不显示。
字符精度:包围字符的外接矩形框,全部在窗口内,则显示。否则不显示。
笔画精度:将笔画变成直线段来进行裁剪,完全就是有多少在窗口内,就显示多少。

7、反走样

相关概念:

走样:用于表示图形的基本单位是一个个离散的像素,这样用离散量表示连续量引起的失真现象。
反走样:用于减少或消除走样现象的技术。

7.1、提高分辨率

把显示器分辨率提高一倍,直线经过两倍的像素,锯齿增加了一倍,但同时每个阶梯的宽度
也减小了一半,由此看上去更加平滑。

7.2、区域采样

基本思想:先假定每个像素是具有一定面积的小区域,然后将直线段看做具有一定宽度的狭长矩
形。当直线段与像素有交时,求出两者相交的面积,然后根据相交的区域面积的大小确定该像素
的亮度值。
缺点:1、像素亮度只与相交区域面积成正比,与相交区域落在像素内的位置无关。
     2、直线条上沿着理想直线方向上的两个像素有时会存在较大的灰度差。

7.3、加权区域采样

基本思想:在区域采样的基础上,将像素划分为n个更小的子像素,并引入了对应的加权表,该加权表为每个子像素对原像素的贡献值(如1/16),通常离中心越近值越大。统计所有中心值落在直线段上的子像素的权值()之和,乘以最大灰度值作为该像素的最大灰度值。

计算机图形学——反走样

8、消隐

相关概念:

消隐:由于显示设备为二维的,当三维模型要显示时,便需要先进行投影变化,但投影变换会失
去深度信息,导致二义性。而消除这种二义性、在绘制时消除被遮挡的不可见的线和面的方法称
为消隐。

消隐按消隐对象分类:
线消隐:消隐对象是物体上的边,消除的是物体上不可见的边。
面消隐:消隐对象是物体上的面,消除的是物体上不可见的面。

消隐按消隐空间分类:
物体空间的消隐算法:将场景中每个面与其他每个面比较,求出所有点、边、面的遮挡关系,
如光线投射算法、Roberts算法。
图像空间的消隐算法:对屏幕上的每个像素进行判断,决定哪个多边形在该像素可见。
例如:Z-Buffer算法、扫描线算法、Warnock算法。
物体空间和图像空间的消隐算法:在物体空间中预先计算main的可见性优先级,
再在图像空间中生成消隐图,例如:画家算法。

前向面:由视点出发的观察向量与某多边形面的法向量相乘的值小于0时的该多边形面。
后向面:由视点出发的观察向量与某多边形面的法向量相乘的值大于0时的该多边形面。

8.1、消除隐藏线

线与线无法产生遮挡关系,只有面和体才能与线产生遮挡关系。
基本运算:判断面对线的遮挡关系。体也可以分解为面,再进行判断。
三种情况:
1、视点与线段在给定平面的同侧,则不遮掩。
2、线段的投影与平面投影无交,则不遮掩。
3、线段的投影与平面投影相交,则求交点,根据交点将线段的投影分成若干段。每一段的中点
如在平面的投影内,则该段被遮挡,否则则显示。

8.2、消除隐藏面
8.2.1、画家算法(列表优先算法):

基本思想:首先将屏幕置为背景色,把物体的每个面按其离视点的远近进行排序,离视点远的放
在前面先绘制,离视点近的放后面后绘制。这样后绘制的面就会覆盖掉先绘制的面。
缺点是:只能处理互不想交的面,而且深度优先列表中面的顺序可能出错。

8.2.2、Z缓冲区(Z-Buffer)算法

基本思想:用帧缓冲区存放每个像素的颜色值,用深度缓存来存放每个像素的深度值。当遍历到
屏幕中一个像素点时,如果(1)该像素点没有在多边形上,则帧缓冲区对应位置置为背景颜色,
如(2)在一个多边形上,则置为该多边形的颜色,
如(3)在多个多边形上,则置为这些多边形中深度(z轴值)最大的那个多边形的颜色。

Z缓冲区算法需要判断一个给定的点是否在多边形内。判断可以采用射线法和弧长法。

射线法

基本思想:由被测点P向y=负无穷方向做射线,如果与多边形的交点个数为奇数,则在多边形内,
为偶数则在多边形外。
如果刚好与多边形的顶点重叠,则采用“左开右闭”原则来计算。
边在射线左侧,则交点个数+1,边在射线右侧,则交点个数不变。

弧长法

基本思想:以被测点P为圆心作单位圆,将全部有向边向单位圆做径向投影,并计算其在单位圆上
弧长的代数和。
如果代数和为0,则点在多边形外部;
如代数和为2π,则点在多边形内部;
如代数和为π,则点在多边形边上。

8.2.3、扫描线Z-Buffer算法

基本思想:与Z-Buffr算法非常相似,区别在于:
(1)将整个绘图窗口内的消隐问题分解到了一条条扫描线上解决,使得所需的Z缓冲区大大减小;
(2)计算深度值时,利用面的连贯性(扫描线的增量计算),只用了一个加法(因为x的增量为1)。
但计算深度时,依旧是按像素点计算。

8.2.4、区域扫描线算法

基本思想:在扫描线Z-Buffer算法的基础上,根据扫描线的投影与多边形的投影相交,
将扫描线分为若干子区间。
每次深度测试,整个子区间一起测试,每次上色时,整个子区间一起上色。

8.2.5、区域子分割算法(Warnack算法)

基本思想:把物体投影到全屏幕窗口上,然后递归的分割窗口,直到窗口内的目标足够简单,
可以显示为止,至多分割窗口至为像素大小。复杂的地方,分割的窗口越多。
个人理解:其实就是把区域扫描线算法的扫描线子区间,改为了窗口子区间。

8.2.6、光线投射算法

基本思想:考察由视点出发穿过观察屏幕的一个像素而射入场景的一条射线,则可以确定出
场景中与该射线相交的物体。

计算机图形学—— 隐藏线和隐藏面的消除(消隐算法)
参考书籍:
《计算机图形学基础教程》 孙家广 胡事民著

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值