图形学笔记1——直线段扫描转换算法

原创 2007年10月11日 02:50:00
 
DDA

已知过端点P0x0, y0, P1 (x1, y1)的直线段; 直线斜率k = (y1-y0) / (x1-x0) .

画线过程为: x的左端点x0开始,向x右端点 步进,步长=1(像素),按y=k x + b 计算相应的y坐标,并去像素点(x, round (y) )作为当前点的坐标。

可以提高效率:

设步长为Δx x i+1 = xi +Δx, 于是: yi+1=kxi+1 +b = kxi + kΔx +b= yi +kΔx

当Δx=1时, yi+1 = yi +k 这样计算每一点,只需做一次加法运算。

note:

round (y) = int (y+0.5) K>1时,必须把x, y的地位互换:y增加1x相应增加1/k

缺点:由于yk须用浮点数表示,每一步都要对y进行四舍五入后取整,使得该算法不利于硬件实现。

 

改进 

目标:进一步将一个加法改为一个整数法加。

 

中点画线法:

通过观察发现,在画线段的过程中,当前像素点为(xp, yp),下一个像素点有两种选择P1xp+1, yp)和P2xp+1, yp+1)。若M=xp+1, yp+0.5)为P1P2之间中点。Q为理想直线与x = xp +1垂线的交点。 则当MQ的下方时,P2为下一个像素点;当MQ的上方时,应取P1为下一点。(如下图)

http://p.blog.csdn.net/images/p_blog_csdn_net/touzani/303255/o_middle.JPG

对直线段Lp0x0, y0, p1(x1, y1) ),采用方程

F (x, y ) = ax+by+c = 0 表示,其中 a = y0 – y1,

b = x1 - x0 ,  c = x0y1 – x1y0

于是有

 线内: F (x, y) = 0

上方: F (x, y) > 0

下方: F (x, y) < 0

要判断MQ点上方还是下方,只要把M点坐标代入F(x, y),并判断符号即可。

即判断 d = F(M) = Fxp+1, yp+0.5= a (xp+1)+ b (yp+0.5) + c 的符号

dxp, yp的线性函数,为提高计算效率,可以采用增量计算。

l       d>=0,则取正右方象素P1 (xp+1, yp), 要判断下一个象素,应计算

     d1= F(xp +2, yp +0.5)=a (xp+2)+ b (yp+0.5) + c = d + a 增量为a

l       d<0,则取右上方象素P2 (xp+1, yp +1)。要判断再下一象素,应计算

     d2= F(xp +2, yp +1.5)=a (xp+2)+b (yp+1.5) + c= d + a + b ;增量为ab

设从点(x0, y0)开始画线,d的初值d0 = F (x0+1, y+0.5) = F ( x0, y0 ) + a + 0.5b.

F ( x0, y0 ) = 0, d0 = a + 0.5 b

进一步,由于d的增量都是整数,只有初始值包含小数,可以用2d代替d来摆脱浮点运算。 这是不影响符号判断的。

 

 

Bresenham算法

Bresenham算法类似于中点法,由误差项符号决定下一个像素取右边点还是右上点。

算法原理:

设直线方程为 y = kx +b, 则有 yi+1= yi + k (xi+1 – xi) = yi + k .

x列的坐标为(xi, yi, 那么下一个像素的列坐标为xi+1,

而行坐标要么仍为yi,要么递增1yi+1

http://p.blog.csdn.net/images/p_blog_csdn_net/touzani/303255/o_bresenham.JPG

是否增1取决于误差项d的值(如上图)

d的初值为0.

x下标每增加1d的值相应增加k.

d0.5时,直线与xi+1列的交点更接近于

像素(xi +1, yi +1),即该像素在y方向递增1.

同时作为下一次计算的基点,因此d值减1.

d<0.5时,交点更接近于像素(xi +1, yi)。

为方便计算,令e = d - 0.5, e的初值为-0.5. 增量为k.

void Bresenhamline (int x0,int y0, int x1, int y1, int color)

/* 起点(x0, y0) 终点(x1, y1)*/

{   int x, y, dx, dy;

    
float k, e;

    dx 
= x1-x0, dy = y1- y0, k=dy/dx;

    e
=-0.5, x=x0, y=y0;

    
for (i=0; i <= dx; i++)

    
{    drawpixel (x, y, color);

          x
=x+1,e=e+k;

          
if (e³0)

          
{ y++, e=e-1;}

    }


}

 

为避免小数与除法,可以改用整数: 做如下替换 e1 = 2 * e * dx

Bresenham画线法程序

void IntegerBresenhamline (int x0,int y0, int x1, int y1, int color)

/* 起点(x0, y0) 终点(x1, y1)*/

{   int x, y, dx, dy, e;

dx 
= x1-x0,  dy = y1- y0,  e = -dx;

    x
=x0, y=y0;

    
for (i=0; i <= dx; i++)  {  

 drawpixel (x, y, color);

          x
=x++,e=e+2*dy;

          
if (e >= 0 )  { y++, e = e - 2*dx; }

    }


}

 

计算机图形学基础 : 基本图形生成算法之直线的扫描转换

数值微分法(DDA)、中点画线法和Bresenham画线算法的学习.
  • JY_95
  • JY_95
  • 2016年08月14日 01:35
  • 1832

计算机图形学--多边形扫瞄转换与区域填充实现

多边形的扫描转换与区域填充。     我选了两个算法实现:        1.多边形扫描转换的X轴扫描线算法        2.区域填充的边界填充算法(填充水平扫描线)。 一、设计思想 多边形扫描...
  • xj2419174554
  • xj2419174554
  • 2013年12月18日 23:32
  • 3417

图形学_椭圆扫描转换_中点椭圆算法

中点椭圆算法 (1)先讨论椭圆弧的上部分    设(Xp,Yp)已确定,则下一待选像素的中点是(Xp+1,Yp-0.5)       d1=F(Xp+1,Yp-0.5)= b2(Xp+1)2+a...
  • bcj296050240
  • bcj296050240
  • 2015年05月15日 16:29
  • 1349

计算机图形学 学习笔记(二):多边形扫描转换:X扫描线算法 和 改进的X扫描线算法

接上文 计算机图形学 学习笔记(一):概述,光栅图形学算法:直线扫描算法(DDA,中点画线算法,Bresenham算法)光栅图形学算法2.4 多边形扫描转换-X扫描线算法多边形的扫描转换和区域填充...
  • Jurbo
  • Jurbo
  • 2017年02月23日 19:46
  • 3001

直线段扫描转换算法-数值微分法(DDA)

在数学上,直线上的点有无穷多个。担当在计算机光栅显示器屏幕上表示这条直线时需要做一些处理。 为了在光栅显示器上用这些离散的像素点逼近这条直线,需要知道这些像素点的x,y坐标。 求出过p0,p1的直...
  • lyp_1020k
  • lyp_1020k
  • 2017年12月02日 23:05
  • 143

计算机图形学(二)输出图元

对于每一类场景,要描述每一对象的结构及其在场景中的坐标位置。图形软件包中用来描述各种图形元素的函数称为图形输出原语(graphics output primitive ),或简称为图元(primiti...
  • heyuchang666
  • heyuchang666
  • 2016年04月14日 16:27
  • 1094

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

前言本笔记基于 http://www.icourse163.org/learn/CAU-45006?tid=1001746004#/learn/announce感谢中国农大 赵明老师的分享~现在我要...
  • Jurbo
  • Jurbo
  • 2016年09月24日 21:33
  • 3342

直线段的扫描转换算法

如何在离散的像素点上画出一条连续的直线,这是直线段的扫描转换算法要研究的内容。 以下画线的代码都只针对斜率在0到1之间的时候的线段。其余斜率的直线画法可以以此类推。 数值微分法      简单的来说,...
  • qq_26010491
  • qq_26010491
  • 2016年10月10日 13:31
  • 375

图形学各种算法代码

目的:实现画直线算法,画圆,画椭圆算法,二维直线裁剪算法 1. DDA算法,算法思想参考百度百科: http://baike.baidu.com/link?url=bKEk1Bmu6YO7gdPu...
  • damotiansheng
  • damotiansheng
  • 2015年01月31日 21:31
  • 3714

图形学_圆的扫描转换

1.中点画圆算法 (1)P为当前点亮象素,那么,下一个点亮的象素可能是P1(Xp+1,Yp)       或P2(Xp +1,Yp +1)。 (2)构造函数:F(X,Y)=X2  +  Y2...
  • bcj296050240
  • bcj296050240
  • 2015年05月15日 16:29
  • 492
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图形学笔记1——直线段扫描转换算法
举报原因:
原因补充:

(最多只允许输入30个字)