当前位置:文档之家› 直线生成算法

直线生成算法

2012-3-31 28
为方便计算,令e=d-0.5,e的初值为-0.5, 增量为k。当e≥0时,取当前象素(xi,yi) 的右上方象素(xi+1,yi+1);而当e<0 时,更接近于右方象素(xi+1,yi)。
2012-3-31
29
Bresenham画线算法程序 void Bresenhamline (int x0,int y0,int x1, int y1,int color) { 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++) { Putpixel (x, y, color); x=x+1; e=e+k; if (e>= 0) { y++, e=e-1;} } }
取整: 取整: xi , yi )}in=0 {(
2012-3-31
{( xi , yi ,r )}in=0
8
yi ,r = round ( yi ) = (int)( yi + 0.5)
复杂度:乘法+加法 取整 复杂度:乘法 加法+取整 加法
DDA算法(增量算法) 算法(增量算法) 算法
= m • xi + B + m = yi + m
2012-3-31
12
改进算法(增量DDA)
增加斜率判断并改变循环参数
2012-3-31
13
DDA画线算法程序(改进)
void LineDDA(int x0,int y0,int x1,int y1,int color) { int x,y;float dx, dy,k,l,m; dx= float(x1-x0); dy= float(y1-y0); k=dy/dx; if abs(k)<1) { for(x=x0; x<= x1, x++) { Setpixel(x, int(y+0.5), color); y+=k; } } else { for(y=y0; y<= y1, y++) { Setpixel(int(x+0.5),y,color); x+=1/k; } } 问题: 如果x0> x1怎么办?
2012-3-31
x=x1; y=y1; k=1; while(k<=length) { SetPixel(hdc,x,y, RGB(0,0,0)); x=x+deltx; y=y+delty; k=k+1; Sleep(50); } }
16
画线中点算法
目标:消除 目标:消除DDA算法中的浮点运算(浮点数取整 算法中的浮点运算
运算,不利于硬件实现; DDA算法,效率低)
条件: 条件:
同DDA算法 算法 斜 率: m ∈ [ 0,1]
直线段的隐式方程( 直线段的隐式方程((x0,y0)(x1,y1)两端点) F(x,y)=ax+by+c=0 式中 a=y0-y1,b=x1-x0,c=X0Y1-X1Y0
2012-3-31
17
2012-3-31 14
DDA直线生成算法的伪语言描述如下: 直线生成算法的伪语言描述如下: 直线生成算法的伪语言描述如下 begin if abs(x2﹣x1)≥abs(y2﹣y1) ﹣ ﹣ then lenght﹦abs(x2﹣x1) ﹦ ﹣ else lenght﹦abs(y2﹣y1) ﹦ ﹣ endif △x﹦(x2﹣x1)/lenght ﹦ ﹣ △y﹦(y2﹣y1)/lenght ﹦ ﹣ x﹦ x﹦x1 y﹦y1 ﹦ k﹦1 ﹦ while(k≤lenght) putpixel(x,y) x﹦x﹢△x ﹦ ﹢ y﹦y﹢△y ﹦ ﹢ k﹦k﹢1 ﹦ ﹢ endwhile end
2012-3-31
6
描绘线条图形的要求
直线段要显得笔直 线段端点位置要准确 线段的亮度要均匀 转换算法速度要快
2012-3-31
7
DDA( digital differential analyzer)算法 ( 算法
条件: 条件:
待扫描转换的直线段: 待扫描转换的直线段:P0 ( x0, y 0) P ( x1, y1) 1 斜率: 斜率:m = ∆y / ∆x
2012-3-31 25
画线Bresenham算法 算法 画线
Bresenham算法是计算机图形学领域使用最广泛的直 线扫描转换算法。该方法类似于中点法,由误差项符 号决定下一个象素取右边点还是右上点。 本算法由Bresenham在1965年提出该方法最初是为数 字绘图仪设计的,后来被广泛地应用于光栅图形显示 和数控(NC)加工 算法原理如下:过各行各列象素中心构造一组虚拟网 格线。按直线从起点到终点的顺序计算直线与各垂直 网格线的交点,然后确定该列象素中与此交点最近的 象素。该算法的巧妙之处在于采用增量计算,使得对 于每一列,只要检查一个误差项的符号,就可以确定 该列的所求象素。
P2 P1 P
2012-3-31 22
d的初始值 d0=F(X0+1,Y0+0.5)=F(X0,Y0)+a+0.5*b 因 (X0,Y0) 在 直 线 上 , F(X0 , Y0)=0, 所 以 , d0=a+0.5*b d的增量都是整数,只有初始值包含小数,可以 用2d代替d, 2a改写成a+a。 算法中只有整数变量,不含乘除法,可用硬件 实现。
∆x = x1 − x0, ∆y = y1 − y 0 直线方程: 直线方程:y = m • x + B 直接求交算法: 直接求交算法: 划分区间[x0,x1]: x0 , x1 , L , xn , 其中xi +1 = xi + 1 划分区间 计算纵坐标: 计算纵坐标: yi = m • xi + B
2012-3-31
4
2 直线段的扫描转换
目标: 目标:求与直线段充分接近的像素集 像素间均匀网格 整型坐标系 两点假设
直线段的宽度为1 直线段的宽度为 直线段的斜率: 直线段的斜率
m ∈ [−1,1]
2012-3-31 5
基本图形点阵转换算法评价
所显示图形的精度 算法的时间和空间复杂性
两者冲突, 两者冲突,权衡折衷
2012-3-31
1
扫描转换直线段
• DDA算法 • 中点画线法 • Bresenham算法
圆弧、椭圆弧扫描转换
• 中点算法
• Bresenham算法 • 内接多边形迫近法* • 等面积多边形逼近法*
2012-3-31
2
1 简单的二维图形显示流程
2012-3-31
3
图形显示前需要:扫描转换+裁剪 ● 裁剪 ---〉扫描转换:最常用,节约计算时间。 ● 扫描转换 ---〉裁剪:算法简单; ● 扫描转换到画布 --〉位块拷贝:算法简单,但耗时耗 内存。常用于字符显示。
2012-3-31
18
直线的正负划分性
点与直线的关系:on: F(x,y)=0; up: F(x, y)>0; down: F(x, y)<0;
2012-3-31
19
欲判断中M在Q点的上方还是下方,只要把M代 F(x,y),并判断它的符号。 构造判别式: d=F(M)=F(xp+1, yp+0.5) =a(xp+1)+b(yp+0.5)+c 当d<0,M在Q点下方,取P2为下一个象素; 当d>0,M在Q点上方,取P1为下一个象素; 当d=0,选P1或P2均可,约定取P1为下一个象 素
2012-3-31
23
中点算法程序 MidPointLine(x0,y0,x1,y1,color) {int x0,y0,x1,y1,color; int a,b,d1,d2,x,y; a = y0-y1; b = x1 – x0; d = 2 * a +b; d1 = 2*a; d2 = 2*(a+b); x = x0; y = y0; SetPixel(x,y,color); while (x<x1) { if (d<0) { x++; y++; d +=d2;} else { x++; d +=d1;} SetPixel(x,y,color); } }
2012-3-31 24
举例 用中点画线方法扫描转换连接两点P0(0,0)和P1 (5,2)的直线段
a=y0-y1=-2; b=x1-x0=5; d0=2*a+b=1; d1=2*a=-4; d2=2*(a+b)=6 x y d 0 0 1 1 0 -3 d1 2 1 3 d2 3 1 -1 d1 4 2 5 d2 5 2 1
第二讲 二维基本图形生成
所谓图元的生成,是指完成图元的参数表示形式(由图 形软件包的使用者指定)到点阵表示形式(光栅显示系 统刷新时所需的表示形式)的转换。通常也称扫描转换 图元 §1 §2 §3 §4 §5 简单的二维图形显示流程 直线段的扫描转换 圆弧的扫描转换 易画曲线的正负法 线画图元的属性控制
2012-3-31
26
工作原理:根据直线的斜率在x或y的方向每次都 只递增一个象素单位,另一个方向的增量为0或1来自2012-3-3127
设直线方程为y=kx+b,其中k=dy/dx。 假 设x列的象素已经确定为xi,其行坐标为yi。 那么下一个象素的列坐标为xi+1,而行坐 标要么不变为yi,要么递增1为yi+1。 是否增1取决于如图所示误差项d的值。因为 直线的起始点在象素中心,所以误差项d的 初值d0=0。X下标每增加1,d的值相应递 d0 0 X 1 d 增直线的斜率值k,即d=d+k。 当d≥0.5时,直线与xi+1列垂直网格交点最 接近于当前象素(xi,yi)的右上方象素(xi +1,yi+1);而当d<0.5时,更接近于右 方象素(xi+1,yi)。
相关主题