定义

图形的扫描转换

  • 图形的扫描转换:在光栅显示器等数字设备上确定一个最佳逼近于图形的像素集的过程。
  • 逼近的过程就是连续量向离散量转换的过程。

基本图形生成算法

直线的扫描转换

数值微分法(DDA:

Digital Differential Analyzer) image.png
特点:

  • 增量算法(最大位移方向+1或-1)
  • 直观、易实现
  • 在此算法中,x、y、k必须是float,且每一步都必须对x、y进行舍入取整,不利于硬件实现。

    中点Bresenham算法

    第三章 基本图形生成算法 - 图5(x为最大位移方向,第三章 基本图形生成算法 - 图6时y为最大位移方向)时Bresenham算法的算法步骤为:

  1. 输入直线的两端点P0(x0,y0)和Pn(xn,yn);
  2. 计算初始值
    1. 第三章 基本图形生成算法 - 图7
    2. 第三章 基本图形生成算法 - 图8
      1. 0<=|k|<=1:image.png
      2. |k|>1:image.png
    3. 第三章 基本图形生成算法 - 图11
  3. 绘制点(x,y)。判断d的符号;
    1. 第三章 基本图形生成算法 - 图12
    2. 若d<0,则(x,y)更新为(x+1,y+1),d更新为 d+1-k;
    3. 否则(x,y)更新为(x+1,y),d更新为 d-k。
  4. 当直线没有画完时,重复步骤3。否则结束。

    用2d∆x代替d

  5. 输入直线的两端点P0(x0,y0)和Pn(xn,y_n);

  6. 计算初始值第三章 基本图形生成算法 - 图13
  7. 绘制点(x,y)。判断d的符号;
    1. 若d<0,则(x,y)更新为(x+1,y+1),d更新为 d+2∆x-2∆y;
    2. 否则(x,y)更新为(x+1,y),d更新为 d-2∆y。
  8. 当直线没有画完时,重复步骤3。否则结束。

    例题

    image.png

    改进的Bresenham算法

    算法步骤

  9. 输入直线的两端点P0(x0,y0)和Pn(xn,y_n);

  10. 计算初始值△x、△y、d=0、x=x0、y=y0;
  11. 绘制点(x,y);
  12. d更新为d+k,判断d的符号。若d>0.5,则(x,y)更新为(x+1,y+1),同时将d更新为d-1;否则(x,y)更新为(x+1,y);
  13. 当直线没有画完时,重复步骤3和4。否则结束。

    改进1:为计算方便,令e=d-0.5

    image.png

  14. 输入直线的两端点P0(x0,y0)和Pn(xn,y_n);

  15. 计算初始值△x、△y、e=-0.5、x=x0、y=y0;
  16. 绘制点(x,y);
  17. e更新为e+k,判断e的符号。若e>0,则(x,y)更新为(x+1,y+1),同时将e更新为e-1;否则(x,y)更新为(x+1,y)。
  18. 当直线没有画完时,重复步骤3和4。否则结束。

    改进2:为方便硬件实现,做以下改进摆脱小数、除法运算:用2e∆x来替换e


image.png

  1. 输入直线的两端点P0(x0,y0)和Pn(xn,y_n);
  2. 计算初始值△x、△y、e=-∆x、x=x0、y=y0;
  3. 绘制点(x,y);
  4. e更新为e+2∆y,判断e的符号。若e>0,则(x,y)更新为(x+1,y+1),同时将e更新为e-2∆x;否则(x,y)更新为(x+1,y)。
  5. 当直线没有画完时,重复步骤3和4。否则结束。

    例题

    image.png

    圆的扫描转换

    简单方程生成圆弧

    极坐标下的参数离散化:image.png

    数值微分算法(DDA)画圆

    基本原理

    image.png
    第三章 基本图形生成算法 - 图20

通过极限思想,逐渐将变化度转化为一个极小量:
q 足够小时有:
第三章 基本图形生成算法 - 图21
方程
第三章 基本图形生成算法 - 图22
可以改写为:
第三章 基本图形生成算法 - 图23
习惯上用e 表示一个较小的量,用它替代q,式子改写为:
第三章 基本图形生成算法 - 图24

特点

  • 简单、直观
  • 计算量大
  • 效率低

    中点Bresenham算法画圆

    原理

    只对(2/Π,4/Π)的八分之一圆进行绘制,其他部分通过对称得到。
    构造函数第三章 基本图形生成算法 - 图25

  • 对于圆上的点,有𝐹(𝑥,𝑦)=0;

  • 对于圆外的点,𝐹(𝑥,𝑦)>0;
  • 而对于圆内的点,𝐹(𝑥,𝑦)<0。

  • 当𝐹(𝑥𝑀,𝑦𝑀)<0时,取𝑃𝑢 (𝑥𝑖+1,𝑦𝑖 )

  • 当𝐹(𝑥𝑀,𝑦𝑀 )>0时,取𝑃𝑑 (𝑥𝑖+1,𝑦𝑖−1)
  • 当𝐹(𝑥𝑀,𝑦_𝑀 )=0时,约定取𝑃𝑢

中点M的坐标为:M(x_i+1,y_i-0.5),
image.png

算法步骤

  1. 输入圆的半径R;
  2. 计算初始值d=1.25-R、x=0、y=R;
    1. image.png
  3. 绘制点(x,y)及其在八分圆中的另外七个对称点;
  4. 判断d的符号。若d≤0,则先将d更新为d+2x+3,再将(x,y)更新为(x+1,y);否则先将d更新为d+2(x-y)+5,再将(x,y)更新为(x+1,y-1);
  5. 当x ≤ y时,重复步骤3和4。否则结束。

    改进

    初始值为1.25-R,会导致出现小数运算,我们将d0=1.25-R改为1-R,则判别式d<=0改为d<=0.25,而由于始终取整数,则判别式可改为d<=0。
    新的算法步骤为:

  6. 输入圆的半径R;

  7. 计算初始值d=1-R、x=0、y=R;
  8. 绘制点(x,y)及其在八分圆中的另外七个对称点;
  9. 判断d的符号。若d≤0,则先将d更新为d+2x+3,再将(x,y)更新为(x+1,y);否则先将d更新为d+2(x-y)+5,再将(x,y)更新为(x+1,y-1);
  10. 当x ≤ y时,重复步骤3和4。否则结束。

    椭圆的扫描转换

    原理

    只对(2/Π,0)的四分之一圆进行绘制,其他部分通过对称得到。
    构造函数,
  • 对于椭圆上的点,有F(x,y)=0;
  • 对于椭圆外的点,F(x,y)>0;
  • 而对于椭圆内的点,F(x,y)<0。


算法原理:

  • 从(0,b)到(a,0)顺时针地确定最佳逼近于第一象限椭圆弧的像素序列。
  • 在上半部分, -1 ≤ k ≤0 , 最大位移方向为x;
  • 在下半部分, k ≤-1 , 最大位移方向为y;
  • 分别对上半部分和下半部分依次判断中点与椭圆边的关系,即:判别式的符号。

    绘制

    上半部分

    判别式:第三章 基本图形生成算法 - 图28

  • 若di≤0,取P_u (x_i+1,y_i )

  • 若di>0,取P_d (x_i+1,y_i-1)

d初值:image.png

下半部分

判别式:第三章 基本图形生成算法 - 图30

  • 若di≤0,取P_r (x_i+1,y_i-1)
  • 若di>0,取P_l (x_i,y_i-1)

d初值:image.png

算法步骤

  1. 输入椭圆的长半轴a和短半轴b;
  2. 计算初始值:d=b2+a^2 (-b+0.25),x=0,y=b;
  3. 绘制点(x,y)及其在四分象限上的另外3个对称点;
  4. 判断d的符号。若d≤0,则先将d更新为d+b2(2x+3),再将(x,y)更新为(x+1,y);否则先将d更新为d+b2(2x+3)+a2(-2y+2),再将(x,y)更新为(x+1,y-1) ;
  5. 当b2(x+1)<a2(y-0.5)时,重复步骤(3)和(4),否则转(6);
  6. 用上半部分计算的最后点(x,y)来计算下半部分中d的初值:d=b^2(x+0.5)^2+a^2(y-1)^2-a2b2 ;
  7. 绘制点(x,y)及其在四分象限的另外3个对称点;
  8. 判断d的符号.若d<=0,则先将d更新为d+b2(2x+2)+a2(-2y+3),再将(x,y)更新为(x+1,y-1);否则先将d更新为d+a2(-2y+3),再将(x,y)更新为(x,y-1);
  9. 当y>=0时,重复步骤(7)和(8),否则结束。

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

    多边形的扫描转换

    多边形的两种表示方法:
  • 顶点表示
  • 点阵表示

多边形的分类

  • 凸多边形
  • 凹多边形
  • 含内环的多边形

    x-扫描线算法

    算法步骤
  1. 确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y值(ymin和ymax);
  2. 从y=ymin到y=ymax,每次用一条扫描线进行填充。对一条扫描线填充的过程可分为四个步骤:
    1. 求交:计算扫描线与多边形各边的交点;
    2. 排序:把所有交点按x值递增顺序排序;
    3. 配对:第一个与第二个,第三个与第四个等等;每对交点代表扫描线与多边形的一个相交区间;
    4. 填色:把相交区间内的像素置成多边形颜色,把相交区间外的像素置成背景色。
      问题
      当扫描线与多边形顶点相交时,会出现异常情况。
      解决方案:
      当扫描线与多边形的顶点相交时,
  • 若共享顶点的两条边分别落在扫描线的两边,交点只算一个;

若共享顶点的两条边在扫描线的同一边,这时交点作为零个或两个;

  • 具体解决方法为:检查共享顶点的两条边的另外两个端点的y值,按这两个y值中大于交点y值的个数是0、1、2来决定交点数取0、1、2。

image.png

缺陷

由于需要求交,需计算扫描线与每条边的交点,效率非常低。

改进的有效边表算法(也叫:y连贯性算法)

两个思想
  • 第一个思想是扫描线的思想,当处理图形图像时按一条条扫描线处理;
  • 第二个思想是增量的思想。

    原理简述
  • 扫描线仅与多边形的有效边进行求交运算。

  • 扫描线的连贯性。当前扫描线与边的交点顺序与下一根扫描线与边的交点顺序大概率一致,不必为下一条扫描线重新构建交点信息。
  • 多边形的连贯性。某边与当前扫描线相交时,大概率也与下一条扫描线相交。

    数据结构
  • 有效边(Active Edge):指与当前扫描线相交的多边形的边,也称为活性边。

  • 有效边表(Active Edge Table, AET):把有效边按与扫描线交点x坐标递增的顺序存放在一个链表中,此链表称为有效边表。
  • 有效边表的每个结点:image.png
    • x为当前扫描线与边的交点的x值
    • ymax为边所在的最大扫描线值
    • 1/k为从当前扫描线到下一条扫描线间x的增量
    • 举例image.pngimage.png
  • 边表(Edge Table, ET):用来存放多边形的边的信息。

    • 解决顶点交点计为1时的情形:
    • image.png
    • 将多边形的某些边缩短以分离那些应计为1个交点的顶点。
    • 若不做该操作,则会导致出现奇数个点,无法两两配对。
      例题
      image.pngimage.png
      image.png
      image.pngimage.png
      image.png
      image.png
      image.png

      区域填充

  • 区域是指已经表示成点阵形式的填充图形,它是像素集合。

  • 区域填充是指将区域内的一点(常称种子点)赋予给定颜色,然后将这种颜色扩展到整个区域内的过程。
  • 区域的表示方法:
    • 边界表示法:把位于给定区域的边界上像素一一列举出来的方法。
    • 内点表示法:枚举出给定区域内所有像素的表示方法。
  • 区域通常分为4-连通区域和8-连通区域两类。
    • 一个点p的4-邻接点是指上、下、左、右四个相邻的点。
    • 一个点p的8-邻接点是指上、下、左、右、左上、右上、左下、右下八个相邻的点。
    • image.png

      边界填充算法

      算法的输入:种子点坐标(x,y),填充色和边界颜色。
      栈结构实现4(8)-连通边界填充算法的算法步骤为:
      种子像素入栈;当栈非空时重复执行如下三步操作:
  1. 栈顶像素出栈;
  2. 将出栈像素置成填充色;
  3. 检查出栈像素的4(8)-邻接点,若其中某个像素点不是边界色且未置成填充色,则把该像素入栈。

image.png

泛填充算法

算法的输入:种子点坐标(x,y),填充色和内部点原来的颜色。

算法原理:
算法从指定的种子(x,y)开始,用所希望的填充颜色赋给所有当前为给定内部颜色的像素点。
种子像素入栈;当栈非空时重复执行如下三步操作:

  1. 栈顶像素出栈;
  2. 将出栈像素置成填充色;
  3. 检查出栈像素的4(8)-邻接点,若其中某个像素点是给定内部点的颜色且未置成新的填充色,则把该像素入栈。

    边界填充算法和泛填充算法的区别

  • 当以边界表示时,4-连通边界填充算法只能填充4-连通区域,8-连通边界填充算法也只能填充8-连通区域。
  • 当以内点表示时,8-连通泛填充算法可以填充8-连通区域也可以填充4-连通区域,当然4-连通泛填充算法还是只能填充4-连通区域。

    扫描转换和区域填充的区别

  • 基本思想不同

    • 多边形扫描转换是指将多边形的顶点表示转化为点阵表示;
    • 区域填充只改变区域的填充颜色,不改变区域表示方法。
  • 基于的条件不同

    • 扫描转换多边形是从多边形的边界(顶点)信息出发,利用多种形式的连贯性进行填充的。
    • 在区域填充算法中,要求给定区域内一点作为种子点,然后从这一点根据连通性将新的颜色扩散到整个区域;

      反走样

      走样:用离散量表示连续量引起的失真,就叫做走样(Aliasing)。
      原理:通过适当地改变图元边界的像素亮度可以平滑边界,从而减小锯齿现象。
      方法:
  • 过取样(supersampling),或后滤波。

    • 简单过取样:切割成更小的子像素。
    • 重叠过取样:在对当前像素着色时同时对周围像素的子像素着色。
    • 基于加权模板的过取样:确定像素亮度时按照对应的加权模板对中心点和四周点的子像素赋予不同的亮度。
  • 区域取样(area sampling),或前滤波。
    • 简单区域采样:绘制有宽度的直线段时,根据所占像素面积的比例来赋予不同的灰度。
      • 通过将每个像素亮度设置成与线条部分重叠的区域面积成正比,可以完成对直线的区域取样。即:若一个像素与线条部分重叠,根据重叠区域面积的大小来选择不同的灰度。重叠面积大的像素更黑一些,重叠面积小的像素更白一些。这种方法将产生模糊的边界,以此来减轻锯齿效应。
      • image.png

6

  1. - 为方便计算,可采用划分更小子像素的方式,以子像素的个数大致估计所占比。
  2. - ![image.png](https://cdn.nlark.com/yuque/0/2020/png/1251173/1590899968596-990eb664-9519-47d4-b196-f0e01e2a3c34.png#align=left&display=inline&height=151&margin=%5Bobject%20Object%5D&name=image.png&originHeight=300&originWidth=283&size=9976&status=done&style=none&width=142)
  • 加权区域取样:假想一个连续的加权曲面(或过滤函数)覆盖像素。当直线条经过该像素时,该像素的灰度值是在二者重叠区域上对滤波器(过滤函数)进行积分的积分值。