第三章 基本图形的扫描转换
- 格式:ppt
- 大小:1.82 MB
- 文档页数:39
第三章作业1.(6分)名词解释:扫描转换、增量算法、反走样。
扫描转换:基本图形的光栅化就是在像素点阵中确定最佳逼近与理想图形的像素点集,并用指定颜色显示这些像素点集的过程。
当光栅化与按扫描线顺序绘制图形的过程集合在一起时,也称为扫描转移。
增量算法:在一个迭代算法中,如果每一步X,Y值是用前一步的值加上一个增量来获得的,那么,这个算法就称为增量算法。
反走样:用于减轻走样的技术称为反走样或者称为抗锯齿。
2.(10分)计算起点坐标为(0,0),终点坐标(12,9)直线的中点Bresenham算法的每一步坐标值以及中点偏差判别式d的值,填入表3-1中,并用黑色绘制图3—29中的直线段的扫描转换像素。
图3—29 像素点阵x y d x y d0 0 —0。
25 7 5 —0.51 1 0 8 6 —0。
252 1 —0.75 9 6 03 2 —0.5 10 7 —0.754 3 -0.25 11 8 -0.55 3 0 12 9 —0.256 4 —0.75表3—1 x,y和d的值第四章作业1.(10分)名词解释:四邻接点、八邻接点、四连通域、八连通域、种子填充算法.四邻接点:对于多边形区域内部任意一个种子像素,其上、下、左、右这四个像素,称为四邻接点。
八邻接点:对于多边形区域内部任意一个种子像素,其上、下、左、右以及左上、左下、右上、右下这八个像素,称为八邻接点.四连通域:对于多边形区域内部任意一个种子子素出发,通过访问其上、下、左、右这四个邻接点可以遍历区域内部的所有像素,该多边形区域称为四连通域.八连通域:对于多边形区域内部任意一个种子子素出发,通过访问其上、下、左、右以及左上、左下、右上、右下这八个邻接点可以遍历区域内部的所有像素,该多边形区域称为八连通域.种子填充算法:从区域内任意一个种子像素开始,由内向外将填充色扩散到整个多边形区域的填充过程。
2. (10分)试写出图4—43所示多边形的边表和扫描线y =4的有效边表。
扫描转换线画图元实验目的:通过上机实践,在C语言环境下实现扫描转换线画图元(直线、圆、椭圆)。
基本思想:利用计算出落在图元上或充分靠近它的一串像素,并以此像素集近似代替原连续图元在屏幕上的显示。
1、扫描转换直线段:(生成直线段的DDA算法)假设需扫描转换的直线段为P0(x0,y0)P1(x1,y1),再令∆x=x1-x0,∆y=y1-y0,斜率m=∆y/∆x,直线方程可以表示为:y=m*x+B ,求表示直线段P 0P1的像素集的最简单方法是利用直线方程直接计算。
以一个像素为单位分割区间[x0,x1],得到上的一个划分:x0,x1,…,x n,根据直线方程得到直线段上对应于横坐标xi的点的纵坐标为y i =m* x i +B,于是就得到了直线段上的点列{(x i,y i)},如图:利用公式:y i+1=mx i+1+B=m(x i+1)+B=mx i+B+m=y i+m得到直线。
2、扫描转换圆弧:该图元是利用圆的八对称性,扫描圆的八分之一弧而进行作图的。
利用函数CirclePoints()显示圆弧上任意一点(x,y)及其七个对称点;如图所示:在作图过程中需要设置中心坐标,否则程序默认圆心(0,0),这样我们看到的将会是1/4圆弧。
关于算法课本中已经讲的很清楚了,这里就不赘述了;3、扫描转换椭圆弧: 我们知道椭圆的方程为: X 2/a+y 2/b=1椭圆弧的画法类似于圆弧的画法,即只需要讨论第一象限内椭圆弧的生成。
进一步可以将椭圆弧分为上下两部分,其分界点为切线斜率为-1的点P ,再由公式: (yy x F x y x F ∂∂∂∂),(,),()=(2b 2x,2a 2y ) 因为(x,y )点的切向与法向垂直,为(-2a 2y , 2b 2x ),从而切线斜率为-1的满足 2b 2x=2a 2y ⇔b 2x=a 2y 由此编程可以得到椭圆。
扫描转换直线段、圆、椭圆的程序如下:#include <stdio.h> #include<graphics.h> #include<math.h> #include<conio.h> /*----画线段----*/void LineDDA(int x0,int y0,int x1,int y1,int color) {int x;float dy ,dx,y ,m; dx=x1-x0; dy=y1-y0; m=dy/dx; y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color); y+=m; }}/*----画圆----*/void CirclePoints( int xo,int yo,int x,int y,int color){putpixel(x+xo,y+yo,color); /*在坐标x,y指定的位置上画一个点*/ putpixel(y+yo,x+xo,color);putpixel(-y+yo,x+xo,color);putpixel(-x+xo,y+yo,color);putpixel(y+yo,-x+xo,color);putpixel(x+xo,-y+yo,color);putpixel(-x+xo,-y+yo,color);putpixel(-y+yo,-x+xo,color);}void MidPointCircle(int xo,int yo,int radius,int color){int x,y,d,deltaE,deltaSE;x=0;y=radius;d=5-4*radius;deltaE=12;deltaSE=20-8*radius;CirclePoints(xo,yo,x,y,color);while(y>x){if(d<=0){d+=deltaE;deltaSE+=8;}else{d+=deltaSE;deltaSE+=16;y--;}deltaE+=8;x++;CirclePoints(xo,yo,x,y,color);}}/*----画椭圆----*/void EllipsePoints(int x_c,int y_c,int x,int y,int color){putpixel(x+x_c,y+y_c, color);putpixel(-x+x_c,y+y_c,color);putpixel(-x+x_c,-y+y_c,color);putpixel(x+x_c,-y+y_c,color);}void MidPointEllipse(int x_c,int y_c,int a,int b,int color) {long x,y,d,xP,yP,squarea,squareb;squarea=(long)a*a;squareb=(long)b*b;xP=(int)(0.5+(float)squarea/sqrt((float)(squarea+squareb))); yP=(int)(0.5+(float)squareb/sqrt((float)(squarea+squareb))); x=0;y=b;d=4*(squareb-squarea*b)+squarea; /*初始化*/ EllipsePoints(x_c,y_c,x,y,color);while(x<=xP){if(d<=0)d+=4*squareb*(2*x+3);else{d+=4*squareb*(2*x+3)-8*squarea*(y-1);y--;}x++;EllipsePoints(x_c,y_c,x,y,color);}x=a;y=0;d=4*(squarea-a*squareb)+squareb;EllipsePoints(x_c,y_c,x,y,color);while(y<=yP){if(d<=0)d+=4*squarea*(2*y+3);else{d+=4*squarea*(2*y+3)-8*squareb*(x-1);x--;}y++;EllipsePoints(x_c,y_c,x,y,color);}}void main(){int a0,b0,a1,b1,c_color;int p0,q0,r,c_color1;int m0,n0,m1,n1,c_color2;int graphdriver,graphmode;graphdriver=VGA;graphmode=VGAHI;initgraph(&graphdriver,&graphmode,"\\TC");cleardevice();printf("enter the line start:");scanf("%d,%d",&a0,&b0);printf("enter the line end:");scanf("%d,%d",&a1,&b1);printf("enter the color mumber:");scanf("%d",&c_color);cleardevice();LineDDA(a0,b0,a1,b1,c_color);getch();cleardevice();printf("enter the center :"); /*输入图圆中心*/scanf("%d,%d",&p0,&q0);printf("enter the radius:"); /*输入图圆半径*/scanf("%d",&r);printf("enter the color mumber:"); /* 输入颜色值*/scanf("%d",&c_color1);cleardevice();MidPointCircle(p0,q0,r,c_color1);getch();cleardevice();printf("enter the center :"); /*输入中心坐标*/scanf("%d,%d",&m0,&n0);printf("enter the chang duan zhou chang:"); /*输入长短轴长*/scanf("%d,%d",&m1,&n1);printf("enter the color mumber:");scanf("%d",&c_color2);cleardevice();MidPointEllipse(m0,n0,m1,n1,c_color2);getch();closegraph();}在程序运行过程中,当然也出现了不少错误,这里只举一两例加以说明(1)、程序在运行过程中,在画椭圆的时候,图象中只有四个点,而不是连续的曲线,经过查阅书籍以及请教同学发现在函数体中缺少了math.h头文件,所以加上文件包含命令#include<math.h>即可出现连续的椭圆图象。