计算机图形学第三章_图形生成技术
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
i
i 1 ,r
1 ) Δy ( x 2) ΔxB 2
i i
1 2 Δ x ( y ) Δ y ( x 1 ) Δ xB Δ y d 0 2 2 Δx( y 1 ) Δy ( x 1) ΔxB Δx Δy d 0 2 x=xi x=xi+1 1 2F( x 1, y ) 2Δy d 0 2 2F( x 1, y 1 ) 2(Δy Δx ) NE d 0 2 (xi,yi) d 0 d 2Δy M (x +1,y ) i i+1 d 2 ( Δ y Δ x ) d 0 E
假定已经求得像素(xi,yi,r),由四舍五入取整原则可知(下图)
1 1 y y ,y 2 2
i i ,r i ,r
由于P0P1的斜率在[0,1]之间,故x = xi +1和P0P1的交点的纵坐标: x=xi x=xi+1 1 3
1 3 y , y 在直线x = xi +1 上,区间 2 2
m=dy/ dx; dy=y2-y1;dx=x2-x1;
画直线算法: 给定直线的两个端点坐标后,求得m和b;然后 在x1≤x≤x2范围内对x取整数,利用公式进行浮点乘法和加法运算, 求得y值后再取整数值,即可得到需要的直线上的像素点。 计算方法的缺点是计算量大。
DDA算法
直线图形上的点是由有先后顺序的一列像素点构成的, 相邻的两点应满足: 于是有: m= (yi+1-yi ) / (xi+1-xi ) yБайду номын сангаас+1 = yi + m(xi+1-xi )
直线段的斜率|k| ≤1;对于斜率 |k| >1 的直线段的生成方法
可对算法做适当改变得到。
3.1直线图形
DDA算法
DDA是数值微分法(Digital Differential Analyzer)的缩写。
设直线起点(x1,y1),终点(x2,y2),则斜率m(|m| ≤1) 为: y=mx+b;b = (y2x1 - y1x2)/(x2 - x1)
中点画线法
计算判别式d 的递推公式如下:
d 2 F ( x 2, y
i 1 i i 1 ,r
1 d 2F(M) 2F( x 1, y ) 2 当d 0 y y y 1当d 0
i i i ,r
i ,r i i 1 ,r i ,r i
1 ) 2 Δx( y 2
i ,r i ,r
y y ,y 2 2
i 1 i ,r i ,r
NE
M
P1
内存在两个像素,NE和E。
(xi,yi) P0 (xi,yi,r)
E
(xi+1,yi+1)
x=xi x=xi+1
中点画线法
NE (xi,yi)
M
根据取整原则,当Q(xi+1,yi+1)在 中点M( xi+1,yi,r+0.5 )上方时,取像 (xi,yi,r) 素NE,否则取像素E,即:
yi1,r yi ,r (E点) yi ,r 1( NE点) 1 1 当yi1 yi ,r , yi ,r 2 2 1 3 当yi1 yi ,r , yi ,r 2 2
E
(xi+1,yi+1)
(1式)
而“(xi+1,yi+1) 在M上方”等价于“F(M)<0”。 欲判断M点是在Q点上方还是在Q点下方,只需把M代入F(x,y),并 检查它的符号。取判别式:
代替d来摆脱小数,提高效率。
中点画线程序
void MidpointLine (int x0,int y0,int x1, int y1,int color) { int △y , △x , d1, d2, d, x, y; △y = y1 - y0; △x =x1-x0; d= △x - 2*△y; d1=-2*△y ; d2=-2* (△y -△x ); x=x0; y=y0; putpixel(x, y, color); while (x<x1) { if (d<=0) {x++; y++; d+=d2;} else {x++; d+=d1;} putpixel (x, y, color); } /* while */ } /* MidPointLine */
i ,r i ,r i i i i ,r i i i ,r i i i i i
(xi,yi,r)
中点画线法
画线从(x0, y0)开始,d的初值
F(x, y) Δxy Δyx ΔxB
d0=2F(x0+1, y0+0.5)= 2[△x (y0 +0.5) - △y(x0 +1) -△xB] = 2[F(x0, y0)+ 0.5△x -△y ] = △x - 2△y
其中(xi,yi)是第i步求得的像素点坐标,(xi+1, yi+1)是第i + 1
步求得的像素点坐标。据前面的分析,应要求:| xi+1-xi | ≤1 | yi+1-yi | ≤1
并要求较大者为1。即如果|m| ≤1 ,则要求
那么,当|m| >1 时,则要求 | xi+1-xi |<1 | yi+1-yi |=1
是浮点数在显示输出时需要取整。中点算法利用“整数加法,
不含乘除法,可用硬件实现”使效率大大提高。 假定直线段的斜率k在[0,1]之间,直线段左下方端点为
P0(x0,y0),右上方端点为P1(x1,y1)。直线段方程为:
Δy x B Δxy Δyx ΔxB Δx F(x, y) Δxy Δyx ΔxB y kx B y
1b
2a 2b 3a
1/m
-1 -1/m -1
1
m 1 -m
则有:
xi+1 = xi + Dx yi+1 = yi +Dy Dy = m ·Dx
3b
4a 4b
-1/m
1 1/m
-1
-m -1
DDA算法
研究表中的数据,可以发现两个规律:
1、当|dx|>|dy|时 |Dx|=1, |Dy|=m; 当|dx|<|dy|时 |Dx| =1/m,|Dy|=1; 2、Dx,Dy的符号与dx,dy的符号相同; 这两条规律可以导致程序的简化。 使用DDA算法,每生成一条直线做两次除法,每画线中一 点做两次加法。因此,用DDA法生成直线的速度是相当快的。
( x , y ) ( x , y ) d Δx 2Δy 算法的初始条件为: d d 2Δy d d 2(Δy Δx)
0 0 ,r 0 0 0 i 1 i i 1 i
di>0 di<=0
由于只用d 的符号作判断,为了只包含整数运算, 可以用2d
第3章 二维图形生成技术
第3章 二维图形生成技术
3.1 3.2 3.3 3.4 直线图形 二次曲线 字 符 区域填充
3.1 直线图形
3.1 直线图形
扫描转换直线段就是计算出落在直线段上或充分靠近它的 一串象素,并以此象素近似代替原连续直线段在屏幕上显示的 过程。本节介绍画线的三个常用算法:数值微分法,中点画线 法和Bersenham法。 为了简化算法,给出两点假设: 直线段的宽度为1;
中点画线法
例:用中点画线法P0(0,0) P1(5,2) △y = y1-y0=2 △x = x1- x0=5 d0 =△x - 2△y=1 d1 = -2△y =-4 i xi yi d 3 1 0 0 1 2 1 0 -3 2 3 2 1 3 1 4 3 1 -1 5 4 2 5 0 1
( x , y ) ( x , y ) d Δx 2Δy d d 2Δy d d 2(Δy Δx ) 当d 0 y y y 1当d 0
当y2-y1 ≥0时: yi+1 = yi +1;xi+1 = xi +1/m;
当y2-y1 ≤0时: yi+1 = yi -1;xi+1 = xi -1/m;
DDA算法
象限 1a |dx|>|dy| ? Dx 1 Dy m 假设: xi+1 - xi =Dx yi+1 - yi =Dy Dy = m ·Dx
基本思想
比较从理想直线到位于直线上方的像素的距离d1和相 邻的位于直线下方的像素的距离d2; 根据距离误差项的符号确定与理想直线最近的象素。
y yk+1 y yk
0
P2
P1 xk xk+1
}
}d
2
d1 x
Bresenham画线法
设直线从起点(x1, y1)到终点(x2, y2)。直线可表示为方程
1 d 2 F ( M ) 2 F ( x 1 , y ) 则(1式)变为: y 2
i i i ,r
i ,r i i 1 ,r i ,r i
当d 0 y (2式) y 1 当 d 0
即1式和2式为中点判别式。
F(x, y) Δxy Δyx ΔxB
# include “conio.h"
# include "graphics.h" # define closegr closegraph
void initgr(void) /* BGI初始化 */
{ int gd=DETECT,gm=0; initgraph(&gd,&gm,""); }
DDA程序
0 0 ,r 0 0 0 i 1 i i 1 i
i ,r i i 1 ,r i ,r i
d 0
i
d 0
i
d2= -2(△y-△x)=6
2
3
4
5
思考题:
MidpointLine算法能实现所有直线的画法吗?
Bresenham画线法
Bresenham画线法
本算法由Bresenham在1965年提出。Bresenham算法是直 线生成算法中最有效的算法之一。
void LineDDA(int x1,int y1,int x2,int y2,int color) { float x,y,dx,dy,k; dx=x2-x1; dy=y2-y1; k=dy/dx; if(k >= -1 && k <= 1) { y=y1; for(x=x1;x<=x2;x++) { putpixel((int)x,(int)(y+0.5),color); y+=k; } } else { k=1/k; x=x1; for(y=y1;y<=y2;y++) { putpixel((int)(x+0.5),(int)y,color); x+=k; } } }
DDA程序
main( ) {initgr( ); /* BGI初始化 */ DDALine(100,100,200,200,6) ; getch( ); closegr( );
}
DDA算法
思考题: DDA算法能实现所有直线的画法吗?
中点画线法
3.1直线图形
中点画线法
影响DDA算法效率的有两点:一是采用了浮点加法;二
DDA算法
例:画直线段P0(0,0) --P1(5,2) x 0 int(y+0.5) 0 y + 0.5 0 + 0.5
1
2 3
0
1 1
0.4+0.5
0.8+0.5 1.2+0.5
3 2 1
Line: P0(0, 0)-- P1(5, 2)
4
5
2
2
1.6+0.5
2.0+0.5
0
1
2
3
4
5
DDA程序
| xi+1-xi | =1
| yi+1-yi | ≤1
DDA算法
于是,画直线的DDA算法可分两种情况描述为:
a. |m| ≤1
当x2-x1 ≥0时: xi+1 = xi +1; yi+1 = yi +m
当x2-x1 ≤0时: xi+1 = xi -1; yi+1 = yi -m
b. |m| >1
F(x,y)=0
直线F(x,y)=0将二维空间成3个部分, 这种性质称为直线的正负划分性。
F(x,y)>0
F(x,y)<0
0
F(x,y)=0
中点画线法
G G G
F(x,y)>0 F(x,y)<0 0
0
x , y F x , y 0; x , y F x , y 0; x , y F x , y 0;
i 1 ,r
1 ) Δy ( x 2) ΔxB 2
i i
1 2 Δ x ( y ) Δ y ( x 1 ) Δ xB Δ y d 0 2 2 Δx( y 1 ) Δy ( x 1) ΔxB Δx Δy d 0 2 x=xi x=xi+1 1 2F( x 1, y ) 2Δy d 0 2 2F( x 1, y 1 ) 2(Δy Δx ) NE d 0 2 (xi,yi) d 0 d 2Δy M (x +1,y ) i i+1 d 2 ( Δ y Δ x ) d 0 E
假定已经求得像素(xi,yi,r),由四舍五入取整原则可知(下图)
1 1 y y ,y 2 2
i i ,r i ,r
由于P0P1的斜率在[0,1]之间,故x = xi +1和P0P1的交点的纵坐标: x=xi x=xi+1 1 3
1 3 y , y 在直线x = xi +1 上,区间 2 2
m=dy/ dx; dy=y2-y1;dx=x2-x1;
画直线算法: 给定直线的两个端点坐标后,求得m和b;然后 在x1≤x≤x2范围内对x取整数,利用公式进行浮点乘法和加法运算, 求得y值后再取整数值,即可得到需要的直线上的像素点。 计算方法的缺点是计算量大。
DDA算法
直线图形上的点是由有先后顺序的一列像素点构成的, 相邻的两点应满足: 于是有: m= (yi+1-yi ) / (xi+1-xi ) yБайду номын сангаас+1 = yi + m(xi+1-xi )
直线段的斜率|k| ≤1;对于斜率 |k| >1 的直线段的生成方法
可对算法做适当改变得到。
3.1直线图形
DDA算法
DDA是数值微分法(Digital Differential Analyzer)的缩写。
设直线起点(x1,y1),终点(x2,y2),则斜率m(|m| ≤1) 为: y=mx+b;b = (y2x1 - y1x2)/(x2 - x1)
中点画线法
计算判别式d 的递推公式如下:
d 2 F ( x 2, y
i 1 i i 1 ,r
1 d 2F(M) 2F( x 1, y ) 2 当d 0 y y y 1当d 0
i i i ,r
i ,r i i 1 ,r i ,r i
1 ) 2 Δx( y 2
i ,r i ,r
y y ,y 2 2
i 1 i ,r i ,r
NE
M
P1
内存在两个像素,NE和E。
(xi,yi) P0 (xi,yi,r)
E
(xi+1,yi+1)
x=xi x=xi+1
中点画线法
NE (xi,yi)
M
根据取整原则,当Q(xi+1,yi+1)在 中点M( xi+1,yi,r+0.5 )上方时,取像 (xi,yi,r) 素NE,否则取像素E,即:
yi1,r yi ,r (E点) yi ,r 1( NE点) 1 1 当yi1 yi ,r , yi ,r 2 2 1 3 当yi1 yi ,r , yi ,r 2 2
E
(xi+1,yi+1)
(1式)
而“(xi+1,yi+1) 在M上方”等价于“F(M)<0”。 欲判断M点是在Q点上方还是在Q点下方,只需把M代入F(x,y),并 检查它的符号。取判别式:
代替d来摆脱小数,提高效率。
中点画线程序
void MidpointLine (int x0,int y0,int x1, int y1,int color) { int △y , △x , d1, d2, d, x, y; △y = y1 - y0; △x =x1-x0; d= △x - 2*△y; d1=-2*△y ; d2=-2* (△y -△x ); x=x0; y=y0; putpixel(x, y, color); while (x<x1) { if (d<=0) {x++; y++; d+=d2;} else {x++; d+=d1;} putpixel (x, y, color); } /* while */ } /* MidPointLine */
i ,r i ,r i i i i ,r i i i ,r i i i i i
(xi,yi,r)
中点画线法
画线从(x0, y0)开始,d的初值
F(x, y) Δxy Δyx ΔxB
d0=2F(x0+1, y0+0.5)= 2[△x (y0 +0.5) - △y(x0 +1) -△xB] = 2[F(x0, y0)+ 0.5△x -△y ] = △x - 2△y
其中(xi,yi)是第i步求得的像素点坐标,(xi+1, yi+1)是第i + 1
步求得的像素点坐标。据前面的分析,应要求:| xi+1-xi | ≤1 | yi+1-yi | ≤1
并要求较大者为1。即如果|m| ≤1 ,则要求
那么,当|m| >1 时,则要求 | xi+1-xi |<1 | yi+1-yi |=1
是浮点数在显示输出时需要取整。中点算法利用“整数加法,
不含乘除法,可用硬件实现”使效率大大提高。 假定直线段的斜率k在[0,1]之间,直线段左下方端点为
P0(x0,y0),右上方端点为P1(x1,y1)。直线段方程为:
Δy x B Δxy Δyx ΔxB Δx F(x, y) Δxy Δyx ΔxB y kx B y
1b
2a 2b 3a
1/m
-1 -1/m -1
1
m 1 -m
则有:
xi+1 = xi + Dx yi+1 = yi +Dy Dy = m ·Dx
3b
4a 4b
-1/m
1 1/m
-1
-m -1
DDA算法
研究表中的数据,可以发现两个规律:
1、当|dx|>|dy|时 |Dx|=1, |Dy|=m; 当|dx|<|dy|时 |Dx| =1/m,|Dy|=1; 2、Dx,Dy的符号与dx,dy的符号相同; 这两条规律可以导致程序的简化。 使用DDA算法,每生成一条直线做两次除法,每画线中一 点做两次加法。因此,用DDA法生成直线的速度是相当快的。
( x , y ) ( x , y ) d Δx 2Δy 算法的初始条件为: d d 2Δy d d 2(Δy Δx)
0 0 ,r 0 0 0 i 1 i i 1 i
di>0 di<=0
由于只用d 的符号作判断,为了只包含整数运算, 可以用2d
第3章 二维图形生成技术
第3章 二维图形生成技术
3.1 3.2 3.3 3.4 直线图形 二次曲线 字 符 区域填充
3.1 直线图形
3.1 直线图形
扫描转换直线段就是计算出落在直线段上或充分靠近它的 一串象素,并以此象素近似代替原连续直线段在屏幕上显示的 过程。本节介绍画线的三个常用算法:数值微分法,中点画线 法和Bersenham法。 为了简化算法,给出两点假设: 直线段的宽度为1;
中点画线法
例:用中点画线法P0(0,0) P1(5,2) △y = y1-y0=2 △x = x1- x0=5 d0 =△x - 2△y=1 d1 = -2△y =-4 i xi yi d 3 1 0 0 1 2 1 0 -3 2 3 2 1 3 1 4 3 1 -1 5 4 2 5 0 1
( x , y ) ( x , y ) d Δx 2Δy d d 2Δy d d 2(Δy Δx ) 当d 0 y y y 1当d 0
当y2-y1 ≥0时: yi+1 = yi +1;xi+1 = xi +1/m;
当y2-y1 ≤0时: yi+1 = yi -1;xi+1 = xi -1/m;
DDA算法
象限 1a |dx|>|dy| ? Dx 1 Dy m 假设: xi+1 - xi =Dx yi+1 - yi =Dy Dy = m ·Dx
基本思想
比较从理想直线到位于直线上方的像素的距离d1和相 邻的位于直线下方的像素的距离d2; 根据距离误差项的符号确定与理想直线最近的象素。
y yk+1 y yk
0
P2
P1 xk xk+1
}
}d
2
d1 x
Bresenham画线法
设直线从起点(x1, y1)到终点(x2, y2)。直线可表示为方程
1 d 2 F ( M ) 2 F ( x 1 , y ) 则(1式)变为: y 2
i i i ,r
i ,r i i 1 ,r i ,r i
当d 0 y (2式) y 1 当 d 0
即1式和2式为中点判别式。
F(x, y) Δxy Δyx ΔxB
# include “conio.h"
# include "graphics.h" # define closegr closegraph
void initgr(void) /* BGI初始化 */
{ int gd=DETECT,gm=0; initgraph(&gd,&gm,""); }
DDA程序
0 0 ,r 0 0 0 i 1 i i 1 i
i ,r i i 1 ,r i ,r i
d 0
i
d 0
i
d2= -2(△y-△x)=6
2
3
4
5
思考题:
MidpointLine算法能实现所有直线的画法吗?
Bresenham画线法
Bresenham画线法
本算法由Bresenham在1965年提出。Bresenham算法是直 线生成算法中最有效的算法之一。
void LineDDA(int x1,int y1,int x2,int y2,int color) { float x,y,dx,dy,k; dx=x2-x1; dy=y2-y1; k=dy/dx; if(k >= -1 && k <= 1) { y=y1; for(x=x1;x<=x2;x++) { putpixel((int)x,(int)(y+0.5),color); y+=k; } } else { k=1/k; x=x1; for(y=y1;y<=y2;y++) { putpixel((int)(x+0.5),(int)y,color); x+=k; } } }
DDA程序
main( ) {initgr( ); /* BGI初始化 */ DDALine(100,100,200,200,6) ; getch( ); closegr( );
}
DDA算法
思考题: DDA算法能实现所有直线的画法吗?
中点画线法
3.1直线图形
中点画线法
影响DDA算法效率的有两点:一是采用了浮点加法;二
DDA算法
例:画直线段P0(0,0) --P1(5,2) x 0 int(y+0.5) 0 y + 0.5 0 + 0.5
1
2 3
0
1 1
0.4+0.5
0.8+0.5 1.2+0.5
3 2 1
Line: P0(0, 0)-- P1(5, 2)
4
5
2
2
1.6+0.5
2.0+0.5
0
1
2
3
4
5
DDA程序
| xi+1-xi | =1
| yi+1-yi | ≤1
DDA算法
于是,画直线的DDA算法可分两种情况描述为:
a. |m| ≤1
当x2-x1 ≥0时: xi+1 = xi +1; yi+1 = yi +m
当x2-x1 ≤0时: xi+1 = xi -1; yi+1 = yi -m
b. |m| >1
F(x,y)=0
直线F(x,y)=0将二维空间成3个部分, 这种性质称为直线的正负划分性。
F(x,y)>0
F(x,y)<0
0
F(x,y)=0
中点画线法
G G G
F(x,y)>0 F(x,y)<0 0
0
x , y F x , y 0; x , y F x , y 0; x , y F x , y 0;