计算机图形学实验报告模板圆的扫描转换
实验报告文档
done=TRUE;
}else if((code0.all&code1.all)!=0){
done=TRUE;
}else{
if(code0.all!=0){
x = x0; y = y0;
dx = x1 - x0; dy = y1 - y0;
d = dx - 2 * dy;
UpIncre=2*dx-2*dy;DownIncre=-2*dy;
while(x<=x1)
{
putpixel(x,y);
printf("x = %d , y = %d \n",x,y);
对剩余部分,把它作为新的线段看待,又从头开始考虑。两遍循环之后,就能确定该线段是部分截留下来,还是全部舍弃。
1、分区编码
延长裁剪边框将二维平面分成九个区域,每个区域各用一个四位二进制代码标识。各区代 码值如图中所示。
2、判别
根据C1和C2的具体值,可以有三种情况:
(1)C1=C2=0,表明两端点全在窗口内,因而整个线段也在窗内,应予保留。
(2)C1&C2≠0(两端点代码按位作逻辑乘不为0),即C1和C2至少有某一位同时为1,表明两端点必定处于某一边界的同一外侧,因而整个线段全在窗外,应予舍弃。
(3)不属于上面两种情况,均需要求交点。
3、求交点
假设算法按照:左、右、下、上边界的顺序进行求交处理,对每一个边界求完交点,并相关处理后,算法转向第2步,重新判断,如果需要接着进入下一边界的处理。
实验
类型
设计型
综合型
创新型
√
实
验
目
的
或
要
求
1.实验内容
计算机图形学画圆实验报告
洛阳理工学院实验报告用纸(2)画理想圆流程图如图-1:图-1:画理想圆流程图(3)中点画圆法图-2 中点画圆法当前象素与下一象素的候选者数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。
(4)Bresenham画圆法Bresenham画线法与中点画线法相似,,它通过每列象素中确定与理想直线最近的象素来进行直线的扫描的转换的。
通过各行,各列的象素中心构造一组虚拟网格线的交点,然后确定该列象素中与此交点最近的的象素。
该算法的巧妙之处在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求对象。
假设x列的象素已确定,其行下标为y。
那么下一个象素的列坐标必为x+1。
而行坐标要么不变,要么递增1。
是否递增1取决于如图所示的误差项d的值。
因为直线的起始点在象素中心,所以误差项d的初始值为0。
X下标每增加1,d的值相应递增直线的斜率值,即d=d+k(k=y/x为直线斜率)。
一旦d>=1时,就把它减去,这样保证d始终在0、1之间。
当d>0.5时,直线与x+1垂直网络线交点最接近于当前象素(x,y)的右上方象素(x+1,y+1);而当d<0.5时,更接近于象素(x+1,y),当d=0。
5时,与上述二象素一样接近,约定取(x+1,y+1)。
令e=d-0。
5。
则当e>=0时,下一象素的y下标增加1,而当e〈0时,下一象素的y下标不增。
E的初始值为-0.5.(二)实验设计画填充点流程图,如图-3:图-3:圆的像素填充过程NS图画理想圆,记录圆心坐标,计算半径大小,并记录是否开始填充否是初始化计数器、标志变量,设置最大计数值调用Bresenha m画圆算法否是填充标记是否为真(While)计数变量小于最大计数值循环变量temp + 1填充计算出来的temp个坐标点计算需要填充坐标数组的前temp个坐标附录图-4 Bresenham画圆算法最终效果图。
第6讲 圆的扫描转换.ppt
d 2(xi yi ) 5
增量为2(xi-yi)+5
d (xi 1)2 ( yi 0.5)2 R2
2021/3/22
信息科学与工程学院
19
判别式d的初始值
y
Pu
PM
Pd
d0 F (1, R 0.5) 1 (R 0.5)2 R2
1.25 R
x
图5-11 中点Bresenham画圆的原理
时间越长。为了在光栅系统上得到连续的边界,可选
取﹦1/R,这样绘制的象素位置大约为一个单位间隔。
此算法也被称为DDA圆的生成算法。
2021/3/22
信息科学与工程学院
12
圆的参数绘制方法C++实现 void ApplicationProceesing() { double xc=300,yc=200,R=150; double x, y, theta, delta; x=xc+R; y=yc; delta=1.0/R; for(theta=0;theta<=2*3.1416;theta=theta+delta) {
d F (xM , yM ) F (xi 1, yi 0.5) (xi 1)2 ( yi 0.5)2 R2
当d≤0时,下一点取Pu(xi +1,yi); 当d>0时,下一点取Pd(xi +1,yi-1)。
2021/3/22
信息科学与工程学院
17
误差项的递推 d≤0: 下一个中点(xi+2, yi -0.5)
2021/3/22
信息科学与工程学院
26
生成圆弧的正负法
即求得Pi点后选择下一个象素点Pi+1的规则为: 当F(xi,yi) ≤0 取xi+1 = xi+1,yi+1 = yi; 当F(xi,yi) >0 取xi+1 = xi, yi+1 = yi - 1; 这样用于表示圆弧的点均在圆弧附近,且使
实验2 圆的扫描转换
实验2 圆的扫描转换一、实验要求基本要求用Bresenham画圆算法实现圆的绘制。
提高要求用Bresenhamg画圆算法实现奥运会五环标志的绘制。
二、实验报告对下列内容逐项填写,适当添加空白页。
1.算法思想Bresenham画圆算法又称中点画圆算法,与Bresenham 直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。
为了简便起见,考虑一个圆心在坐标原点的圆,而且只计算八分圆周上的点,其余圆周上的点利用对称性就可得到。
为什么只计算八分圆周上的点就可以了。
和直线算法类似,圆也有一个“八对称性”。
显然,我们只需要知道了圆上的一个点的坐标 (x, y) ,利用八对称性,我们马上就能得到另外七个对称点的坐标。
和直线算法类似,Bresenham画圆算法也是用一系列离散的点来近似描述一个圆。
2.程序流程图2.源程序清单和结果画圆的程序int d,x,y,x0,y0,r=100;d=3-2*r; x=0; y=r; x0=200; y0=200; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB(0,0,0)); if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB(0,0,0)); pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,0)); pDC->SetPixel(-x+x0,y+y0,RGB(0,0,0)); pDC->SetPixel(-y+x0,x+y0,RGB(0,0,0)); pDC->SetPixel(-y+x0,-x+y0,RGB(0,0,0)); pDC->SetPixel(y+x0,x+y0,RGB(0,0,0)); pDC->SetPixel(y+x0,-x+y0,RGB(0,0,0)); }五环程序int d,x,y,x0,y0,r=53;d=3-2*r; x=0; y=r; x0=200; y0=200; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB(0,0,255));if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB(0,0,255));pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,255));pDC->SetPixel(-x+x0,y+y0,RGB(0,0,255));pDC->SetPixel(-y+x0,x+y0,RGB(0,0,255));pDC->SetPixel(-y+x0,-x+y0,RGB(0,0,255));pDC->SetPixel(y+x0,x+y0,RGB(0,0,255));pDC->SetPixel(y+x0,-x+y0,RGB(0,0,255));}d=3-2*r; x=0; y=r; x0=320; y0=200; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB(0,0,0));if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB(0,0,0));pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,0));pDC->SetPixel(-x+x0,y+y0,RGB(0,0,0));pDC->SetPixel(-y+x0,x+y0,RGB(0,0,0));pDC->SetPixel(-y+x0,-x+y0,RGB(0,0,0));pDC->SetPixel(y+x0,x+y0,RGB(0,0,0));pDC->SetPixel(y+x0,-x+y0,RGB(0,0,0));}d=3-2*r; x=0; y=r; x0=440; y0=200; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));}d=3-2*r; x=0; y=r; x0=260; y0=260; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB(255,255,0));if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB(255,255,0));pDC->SetPixel(-x+x0,-y+y0,RGB(255,255,0));pDC->SetPixel(-x+x0,y+y0,RGB(255,255,0));pDC->SetPixel(-y+x0,x+y0,RGB(255,255,0));pDC->SetPixel(-y+x0,-x+y0,RGB(255,255,0));pDC->SetPixel(y+x0,x+y0,RGB(255,255,0));pDC->SetPixel(y+x0,-x+y0,RGB(255,255,0));}d=3-2*r; x=0; y=r; x0=380; y0=260; //(x0,y0)圆心坐标while(y>=x){ pDC->SetPixel(x+x0,y+y0,RGB( 0,255,0));if(d<0)d=d+4*x+6;elsed=d+4*x-4*y+10,y--;x++;pDC->SetPixel(x+x0,-y+y0,RGB( 0,255,0));pDC->SetPixel(-x+x0,-y+y0,RGB( 0,255,0));pDC->SetPixel(-x+x0,y+y0,RGB( 0,255,0));pDC->SetPixel(-y+x0,x+y0,RGB( 0,255,0));pDC->SetPixel(-y+x0,-x+y0,RGB( 0,255,0));pDC->SetPixel(y+x0,x+y0,RGB( 0,255,0));pDC->SetPixel(y+x0,-x+y0,RGB( 0,255,0));}4.实验总结Bresenham确实是一种很快速的的算法。
计算机图形学——圆的扫描转换(基本光栅图形算法)
计算机图形学——圆的扫描转换(基本光栅图形算法)与直线的⽣成类似,圆弧⽣成算法的好坏直接影响到绘图的效率。
本篇博客将讨论圆弧⽣成的3个主要算法,正负法、Bresenham 法和圆的多边形迫近法,在介绍算法时,只考虑圆⼼在原点,半径为R的情况。
⼀、正负法1、基本原理假设已选取Pi-1为第i-1个像素,则如果Pi-1在圆内,就要向圆外⽅向⾛⼀步;若已在圆外就要向圆内⾛⼀步。
总之,尽量贴近圆的轮廓线。
2、正负法的具体实现1)圆的表⽰:设圆的圆⼼为(0,0),半径为R,则圆的⽅程为:F(x,y)=x2+y2–R2=0当点(x,y)在圆内时,F(x,y)<0。
当点(x,y)在圆外时,F(x,y)>0。
2)实现步骤第1步:x0=0,y0=R第2步:求得Pi(x i,y i)后找点P i+1的原则为:当P i在圆内时(F(xi,yi)≤0),要向右⾛⼀步得P i+1,这是向圆外⽅向⾛去。
取x i+1= x i+1, y i+1= y i当P i在圆外时(F(xi,yi)>0),要向下⾛⼀步得P i+1,这是向圆内⽅向⾛去,取x i+1= x i, y i+1= y i-1⽤来表⽰圆弧的点均在圆弧附近且 F(xi, yi)时正时负假设已经得到点(x i, y i),则容易算出F(x i, y i),即确定了下⼀个点(x i+1, y i+1),则如何计算F(x i+1, y i+1),以确定下下个点(x i+2, y i+2)?分为两种情况:右⾛⼀步后:x i+1=x i+1,y i+1=y i,此时:F(x i+1, y i+1)=x i+12+y i2-R2=x i2+y i2-R2+2x i+1 = F(x i, y i)+2x i+1下⾛⼀步后:x i+1=x i,y i+1=y i-1, 此时:F(x i+1, y i+1)=x i2+(y i-1)2-R2= F(x i, y i)-2y i+1由此可得:确定了F(xi+1, yi+1)之后,即可决定下⼀个点(xi+2, yi+2),选择道理同上。
圆的扫描转换原理
1)若 ( , )<0,说明点 在圆内,则下一步应向圆外走,即 取
= +1, = 。
2)若 ( , )>0,说明点 在圆外,则下一步应向圆内走,即 取
= , = -1。
3)若 ( , )=0,说明点 在圆上,则下一步可以向圆外走,也可以向圆外走,这里规定 取 = +1, = 。
设R为弧AB的半径,记点P到原点的距离的平方பைடு நூலகம்圆的半径的平方之差为D(P),即
D(P)=( + -
根据D(P)定义,如果点Q在圆内,则D(Q)<0,如果Q在圆外,则D(Q)>0。假定 为圆弧上的点,则D( )>0,D( )<0。令
=D( )+D( )=( +1)2+ - +( -1)2+( -1)2-
正负法:该方法主要用于笔试绘图仪中,由于笔试绘图仪只有水平或垂直方向的运动,绘图笔每次只能向正右方或正下方运动,因此相应地在画圆时,只能从当前像素移动到其正右方或正下方的像素。
圆心在原点、半径R的圆方程的函数表达式为:
F(x,y)= + - =0
对于圆上的点,F(x,y)=0;对于圆内的点,F(x,y)<0;对于圆外的点,F(x,y)>0。对于第一象限内四分之一圆弧AB的绘制方法,利用对称性很容易绘制圆的其他部分。这里顺时针方向生成圆弧,并假定圆心和起点均精确地落在像素上。设起点A为 ( , ),则有 =0, =R。
Bresenham算法:画第一象限内八分之一个圆AB,从A点开始,顺时针画点,其他7个对称点即可。
从点A开始向右下方逐点寻找显示弧AB要用的点,如果 是已选中的一个表示圆弧上的点,由于圆弧在A、B两点之间斜率小于等于1,所以下一个点 ( +1, )或 ( +1, -1),选 还是选 ,取决于哪一个点更接近于弧AB。
计算机图形学之扫描转换线画图元的方法
扫描转换线画图元实验目的:通过上机实践,在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>即可出现连续的椭圆图象。
计算机图形学实验报告模板圆的扫描转换
北京联合大学应用文理学院实验报告课程名称计算机图形学实验(实训)名称圆的扫描转换班级信息与计算科学2009级姓名学号同组者实验(实训)日期完成日期本实验(实训)所用学时统计预习实验(实训)报告总计评阅意见:成绩北京联合大学应用文理学院实验报告一、实验目的1、掌握用中点画圆法进行圆的扫描转换方法;2、掌握用Bresenham画圆法进行圆的扫描转换方法;3、理解中点画圆法与Bresenham画圆法的区别;二、算法原理介绍1、中点画圆算法假设x坐标为xp的各像素点中,与该圆弧最近者已确定,为P(xp,yp),那么,下一个与圆弧最近的像素只能是正右方的P1(xp+1,yp),或右下方的P2(xp+1,yp-1)两者之一。
令M为P1和P2的中点,易知M的坐标为(xp+1,yp-0.5)。
显然,若M在圆内,则P1离圆弧近,应取为下一个像素;否则应取P2。
判别式d:d = F(M)=F(xp+1,yp-0.5)=(xp+1)^2+(yp-0.5)^2-R^2d的初始值为:d0 = F(1,R-0.5)=1+(R-0.5)^2-R^2=1.25-R在d≥0的情况下,取右下方像素P2,d = F(xp+2,yp-1.5)=(xp+2)^2+(yp-1.5)^2-R^2=d+2(xp-yp)+5在d<0的情况下,取正右方像素P1,d = F(xp+2,yp-0.5)=(xp+2)^2+(yp-0.5)^2-R^2=d+2xp+32、 Bresenham画圆算法假设生成圆心在坐标原点,半径为r,从x=0到x=y的1/8圆弧。
xi+1=xi +1相应的y则在两种可能中选择:y=yi,或者y=yi-1选择的原则是考察理想的y值是靠近yi还是靠近yi-1判别式:d i+1=2(xi+1)2+yi2+(yi-1)2-2r2判断式d的初始值为:d0= 3-2r。
如果d i+1>=0,则y=yi-1,di+2 =d i+1 + 4(xi- yi)+10如果d i+1<0,则y=yi,d i+2 =d i+1+ 4x i+6三、程序源代码1、中点画圆算法#include"graphics.h"#include"math.h"#include"conio.h"main(){void MidPointCircle(int,int);/*定义主函数变量,MidPointCircle中点画圆算法函数*/int gdriver,gmode; /*gdriver和gmode分别表示图形驱动器和模式*/gdriver=DETECT; /*DETECT是自动选择显示模式*/initgraph(&gdriver,&gmode,"c:\\tc3.0\\BGI");/*图形驱动文件的路径*/ MidPointCircle(200,YELLOW); /*定义圆的半径和颜色*/getch();/*getch();会等待你按下任意键,再继续执行下面的语句*/closegraph();/*关闭图形系统*/return(0); /*返回值为0*/}void MidPointCircle(int r,int color) /*定义函数变量半径和颜色*/{ int x,y;float d; /*float类型中小数位数为7位,即可精确到小数点后7位 */x=0; y=r; d=1.25-r;while(x<y) /*满足条件x<y时进入循环,不满足跳出*/{ if(d<0){d+=2*x+3; x++;}else { d+=2*(x-y)+5; x++; y--;}putpixel(x+200,y+200,color); putpixel(y+200,x+200,color);putpixel(200-x,y+200,color); putpixel(y+200,200-x,color);putpixel(200+x,200-y,color); putpixel(200-y,x+200,color);putpixel(200-x,200-y,color); putpixel(200-y,200-x,color);/* putpixel 在指定位置画一像素*/}}2、 Bresenham画圆算法#include"graphics.h"#include"math.h"#include"conio.h"main(){void Bresenham_Circle(int,int);/* Bresenham_Circle为 Bresenham画圆算法函数*/int gdriver,gmode;gdriver=DETECT;initgraph(&gdriver,&gmode,"c:\\tc3.0\\BGI");Bresenham_Circle(200,YELLOW); /*定义圆的半径和颜色*/getch();closegraph();return(0);}void Bresenham_Circle(int R,int color){ int x,y,delta,delta1,delta2,direction;x=0;y=R;delta=2*(1-R);while(y>=0) /*满足条件y>=0时进入循环,不满足跳出*/{putpixel(x+200,y+200,color); putpixel(y+200,x+200,color);putpixel(200-x,y+200,color); putpixel(y+200,200-x,color);putpixel(200+x,200-y,color); putpixel(200-y,x+200,color);putpixel(200-x,200-y,color); putpixel(200-y,200-x,color);if(delta<0){delta1=2*(delta+y)-1;if(delta1<=0)direction=1;else direction=2;}else if(delta>0){delta2=2*(delta-x)-1;if(delta2<=0) direction=2;else direction=3;}elsedirection=2;switch (direction)/*switch语句,即“切换”语句;case即“情况*/ {case 1:x++;delta+=2*x+1;break;/*执行 break 语句会退出当前循环或语句*/case 2:x++;y--;delta+=2*(x-y+1);break;case 3: y--;delta+=(-2*y+1);break;}}}四、实验结果图1中点画圆算法生成的圆半径r=200,颜色为黄色图2 Bresenham画圆算法生成的圆半径R=200,颜色为黄色五、总结与体会通过运用 C 语言环境下的图像显示设置,本次实验我学会了用中点画圆法、Bresenham 画圆法进行圆的扫描转换,更加深刻的理解了中点画圆法、Bresenham 画圆法进行圆的扫描转换的生成原理。
图形学画圆实验报告参考模板
4.2.3程序实现与上机实习(二)一、实验目的编写圆和椭圆的扫描转换算法程序,验证算法的正确性。
二、实验任务1.编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;2.添加鼠标程序,实现交互式画圆;3.编写中点画椭圆法的扫描转换程序;4.添加鼠标程序,实现交互式画椭圆;三、实验内容1.编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;分析:考虑圆心不再原点,设圆心坐标为(x0,y0)。
通过平移坐标原点到圆心,则第二个8分圆上一点p(x,y),其原始坐标为x’=x+x0y’=y+y0即p’1(x0 +x, y+y0)其它7个对称点分别是:p’2(x0+y,y+x0), p’3 (x0+y,y0-x),p’4 (x0+x,y0-y),p’5 (x0-x,y0-y),p’6 (x0-y,y0-x),p’7 (x0-y,y0+x),p’8 (x0-x,y0+y)算法程序如下:{int x,y;float d;x=0;y=r;d=1.25-r;CirPot(x0,y0,x,y,color);while (x<=y){if(d<0){d+=2*x+3; x++;}(x0+R,y0)else{d+=2*(x-y)+5;x++; y--;}CirPot(x0,y0,x,y,color);} /* while*/} /* MidpointCiecle */int CirPot(int x0,int y0,int x,int y,int color){Setpixel((x0+x),(y0+y));Setpixel((x0+y),(y0+x));Setpixel((x0+y),(y0-x));Setpixel((x0+x),(y0-y));Setpixel((x0-x),(y0-y));Setpixel((x0-y),(y0-x));Setpixel((x0-y),(y0+x));Setpixel((x0-x),(y0+y));}程序实现步骤:(1)建立MidPointCircle工程文件;(2)右击CMidPointCircleView类,建立成员函数void MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color)int CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color)(3) 编写成员函数代码,程序如下:void CMidPointCircleView::MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) {int x,y;float d;x=0;y=r;d=1.25-r;CirPot(pDC,x0,y0,x,y,color);while (x<=y){if(d<0){d+=2*x+3; x++;}else{d+=2*(x-y)+5;x++; y--;}CirPot(pDC,x0,y0,x,y,color);} /* while*/}int CMidPointCircleView::CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) {pDC->SetPixel((x0+x),(y0+y),color);pDC->SetPixel((x0+y),(y0+x),color);pDC->SetPixel((x0+y),(y0-x),color);pDC->SetPixel((x0+x),(y0-y),color);pDC->SetPixel((x0-x),(y0-y),color);pDC->SetPixel((x0-y),(y0-x),color);pDC->SetPixel((x0-y),(y0+x),color);pDC->SetPixel((x0-x),(y0+y),color);return 0;}(4)编写OnDraw(CDC* pDC)函数,程序如下:void CMidPointCircleView::OnDraw(CDC* pDC){CMidPointCircleDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data hereMidpointCircle(pDC,100, 100, 10, RGB(255,0,0));MidpointCircle(pDC,500, 300, 60, RGB(255,255,0));}(6)编译、运行程序,查看结果。
计算机图形学(圆弧的扫描转换II)
椭圆弧 的生成
xi 1 a cos( i ) , yi 1 b sin( i )
由此可得
xi 1 xi y M y i 1 i
cos 其中 M b sin a
a sin b cos
P(xi,yi) P (x +1,y ) u i i M(xi+1,yi-0.5) Pd(xi+1,yi-1)
如果d1i >0,中点在椭圆外,应取右下方像素Pd(xi+1,yi-1) 判别式更新为:d1(i+1)=F(xi+2,yi-1.5)=d1i+b2(2xi+3)+2a2(-yi+1) 如果d1i ≤0,中点在椭圆内,应取正右方像素Pu(xi+1,yi) 判别式更新为:d1(i+1)=F(xi+2,yi-0.5)=d1i+b2(2xi+3) 判别式初值为:d10=F(1,b-0.5)=b2+a2(-b+0.25)
■ 圆穿越⑤区域时,D(Hi) > 0,D(Li) = 0,有 Di = | D(Hi) |-| D(Li) | = D(Hi) = di
结论: di的符号与Di的符号是否一致
2009-2010-2:CG:SCUEC
6
判别式di的增量计算
di = D(Hi)+D(Li) = [(xi-1+1)2+yi-12-R2]+[(xi-1+1)2+(yi-1-1)2-R2] 若di<0,表示Hi点更接近圆周,
2009-2010-2:CG:SCUEC
3
判别式的改进
用高级语言实现圆的生成(圆的扫描转换)
集美大学计算机工程学院实验报告课程名称计算机图形学教程实验名称实验三、用高级语言实现圆的生成(圆的扫描转换)实验类型设计型姓名罗忠霖学号2010810072日期11月28日地点陆大206成绩教师庄建东一、实验目的:1、培养学生动手编程解决实际问题的能力。
2、训练学生分析问题和调试程序的能力。
3、锻炼学生撰写科技实验论文的能力二、实验内容:组1:用中点画圆弧方法1.先画半径为100的1/4圆弧2.半径依次递减1个单位,再画同一个圆心的1/4圆弧3.直到半径为504.过程要有延时5.若在递减1个单位的同时,画出7种颜色,如何做?三、实验要求:1、问题分析充分地分析和理解问题本身,弄清要求做什么,用什么算法。
1). 了解圆弧的扫描转换方法;2). 掌握圆弧的扫描转换方法的原理及其实现方法;3).掌握圆弧的生成方法;4).课时:22、程序设计(1)根据所采用的算法,设计数据结构,画出流程图并编程。
(2)最后准备调试程序的数据及测试方案。
3、上机调试(1)对程序进行编译,纠正程序中可能出现的语法错误。
(2)调试前,先运行一遍程序看看究竟将会发生什么。
(3)如果情况很糟,根据事先设计的测试方案并结合现场情况进行错误跟踪,包括单步调试、设置观察窗输出中间变量值等手段。
4、整理实习报告实验报告1、实习内容:采用的算法名称2、问题描述:包括目标、任务、条件约束描述等。
3、设计:数据结构设计和核心算法设计。
主要功能模块的输入,处理(算法框架)和输出。
4、测试范例:测试结果的分析讨论,测试过程中遇到的主要问题及所采用的解决措施。
5、心得:包括程序的改进设想,经验和体会。
6、程序清单:源程序,其中包括变量说明及详细的注释。
四、实验环境:1.PC,CPU:P4 2.0GHz以上,内存:512M,硬盘:40GB以上;2.操作系统:Microsoft Windows 2000 /2003/XP;3.软件:VC或JAVA等。
五、实验内容及完成情况:采用中点画圆弧方法#include "graphics.h"#include "math.h"#include "stdio.h"#include "conio.h"#include "stdlib.h"void WholeCircle(int xc, int yc, int x, int y, int color){putpixel (xc + x,yc - y,color);putpixel (xc + y,yc-x,color);}void MidpointCircle (int xc, int yc, int x,int y,int d,int r, int color) {WholeCircle(xc,yc,x,y,color);while(x<=y){ if(d<0){d+=2 * x+3;x++;}else{d+=2*(x-y)+ 5;x++; y--;}WholeCircle(xc,yc,x,y,color);}}void main(){int xc=300,yc=200,r=100,color=7;int x=0, y=r,d=1-r;int driver=DETECT,mode=0;initgraph(&driver,&mode,"");printf("\n 计算1013 罗忠霖 2010810072\n");for(;y>=50;y--,color--){MidpointCircle(xc,yc,x,y,d,r,color);if(color==-1)color=7;delay(100);}getch();}运行结果:六、实验总结:1.通过本次实验,初步了解了计算机图形学在计算机图像处理,工程制图,平面设计上面的应用,2.掌握了计算机绘制圆的几种算法,圆的生成算法,圆的生成算法,和圆的参数生成方法。
图形学(直线,圆)实验报告
实验:直线及圆的扫描转换姓名:龙泽学号:20141090068 学院:职继学院指导教师:吴昊课程:计算机图形学一.实验内容:直线Bresenham算法二.实验设计输入:直线段的两个端点,起始点(X0,Y0),终点(X1,Y1),线段的颜色(color)处理过程:1.输入线段的两个端点坐标和画线颜色:x1,y1,x2,y2,color;2.设置象素坐标初值:x=x1,y=y1;3.设置初始误差判别值:p=2·Δy-Δx;4.分别计算:Δx=x2-x1、Δy=y2-y1;5.然后对起点和终点的x和y的大小的比较,以判断直线的斜率;6.循环实现直线的生成;7.输出: 显示以(X0,Y0)和(X1,Y1)为端点的直线段,颜色为color 三.程序清单实验代码如下:#include <windows.h>#include <GL/glut.h>//初始化OpenGL场景void myinit (void){glClearColor (250.0, 250.0, 250.0, 0.0); //将背景置成黑色glMatrixMode(GL_PROJECTION);gluOrtho2D(0,500,0,500);//设置投影变换,使用正交投影}void setPixel(int x, int y,int color)//在指定位置(x,y)绘制点图元{glBegin (GL_POINTS);glVertex2i(x,y);//绘制点的坐标glEnd ( );}//bresenha绘制直线的方法void Bresenhamline (int x1,int y1,int x2,int y2,int color)//输入线段的两个端点坐标和画线颜色{int x,y,dx,dy,s1,s2,p,temp,interchange,i;x=x1;y=y1;//设置象素坐标初值dx=abs(x2-x1);dy=abs(y2-y1);//分别计算之间的差值if(x2>x1)s1=1;elses1=-1;if(y2>y1)s2=1;elses2=-1; //判断起点和终点的位置,以确定是该加一个单位还是该减一个单位if(dy>dx)//y方向增长快,将总步数设为y2-y1,每一步的y值为:y=y+1{temp=dx;dx=dy;dy=temp;interchange=1;}elseinterchange=0;//x方向增长快,将总步数设为x2-x1,每一步的x值为:x=x+1p=2*dy-dx; //设置初始误差判别值for(i=1;i<=dx;i++){setPixel(x,y,color);if(p>=0){if(interchange==0)y=y+s2;elsex=x+1;p=p-2*dx;}if(interchange==0)x=x+s1;elsey=y+s2;p=p+2*dy;}}//用户的绘图过程void display(void){glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除缓存glColor3f(0,0,255); //给定直线的颜色Bresenhamline (50,150,400,300,0); //给定直线的起点坐标和重点坐标 glFlush (); //绘图结束}//主过程:// 初始化Windows的窗口界面// 并初始化OpenGL场景,绘图int main(int argc, char** argv){glutInit(&argc, argv); //初始化glutglutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); //初始化显示模式,采用单缓存,RGB彩色系统glutInitWindowSize (500, 500); //初始化窗口大小glutInitWindowPosition (100, 100); // 初始化窗口位置glutCreateWindow ("第一个OpenGL程序"); //创建窗口myinit (); //自定义初始化glutDisplayFunc(display); //注册显示函数glutMainLoop(); //进入OpenGL的主循环。
实验2 圆的扫描生成算法
实验2圆\椭圆的扫描生成算法一、实验目的理解圆\椭圆的扫描生成原理,掌握圆\椭圆的扫描生成算法。
二、实验内容用Bresenham算法画圆的步骤为:(1)求误差初值,p1=3-2r;i=1;画点(0,r);(2)求下一个光栅位置:x i+1=x i+1;if p i<0则y i+1=yi;否则y i+1=y i-1;(3)画点(x i+1,y i+1);(4)计算下一个误差:if p i<0则p i+1=p i+4x i+6;否则p i+1=p i+4(x i-y i)+10;(5)i=i+1;if x=y则end;否则返2)。
用Bresenham算法画椭圆的步骤为:(1)输入椭圆长半轴的长度a和短半轴的长度b上半段(2)求误差初值d10,d10=b2+a2(-b+0.25),将该值赋给变量d;(3)绘制点(x,y),其中x=0,y=b及其在另外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)时,重复步骤三和四,否则,转到步骤六。
下半段(6)计算下半部分的判别式初值d20,d20=b2(x+0.5)2+a2(y-1)2-a2b2,其中(x,y)是上半部计算的最后一点(x,y),计算后将d20赋给变量d;(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时,重复步骤七和八,否则,算法结束。
三、实验要求编程实现Bresenham算法生成圆\椭圆。
计算机图形学实验报告
院系:计算机科学学院
专业:软件工程
年级: 2012 级
课程名称:计算机图形学
班号:软工3班
组号: 35组
指导教师:
2014年 11月 10 日
直线的扫描转换—DDA算法
图1-2 直线的扫描转换—Bresenham算法
DDA算法实现的直线的扫描转换图,图1-2是Bresenham算法实现的直线的扫描转换图。
从结果可以得到,程序可以显示鼠标的当前坐标,鼠标的起点坐标及鼠标的终点坐标;当执行时,网格会用红方格描出直线的像素点,并在表格中输出相应值和Y值,直至描述到直线的最后一个点,程序才结束,图形生成过程可以重复进行,只需对上次图形点击清除键清除后。
图4-1 多边形的绘制图
图2-3 正负法画圆弧显示图
图2-4 Bresenham法画圆弧
从结果页面可知,程序可以显示鼠标的当前坐标,圆心坐标及圆的半径;当执行时,会用红方格描出圆的各个像素点,随即进行45度对称翻转,X轴对称翻转,
对称翻转,并在表格中输出相应的D值,X值和Y值,图形生成过程可以重复进行,只需对上次图形点击清除键清除后。
该程序能应用和正负法Bresenham
的像素描点,程序显示结果直观、易操作。
但有时描出的点也存在一些误差,原因分析可能在于像素单元定的太大了(每20格定义为一个大像素单元)。
图3-1直线段的裁剪初始图
图3-3 直线段的裁剪初始图裁剪图。
计算机图形学圆的扫描转换
② 误差项的递推
d≤0:
d = F ( x i + 2 , y i 0 .5) = ( x i + 2 ) 2 + ( y i 0 .5 ) 2 R 2 = ( x i + 1) 2 + ( y i 0 .5 ) 2 R 2 + 2 x i + 3 = d + 2 xi + 3
yi
P
② 误差项的递推
③
判别式的初始值
d
0
= F (1 , R 0 . 5 ) = 1 + ( R 0 .5 ) 2 R = 1 .2 5 R
2
判别式的递推
d i +1 = d i + 2 x i + 3 d i +1 = d i + 2( x i y i ) + 5 d i <= 0 di > 0
x与y的更新
构造函数F(x,y)=x2+y2-R2 对于圆上的点,有F(x,y)=0
y
x
3.中点Bresenham画圆 3.中点Bresenham画圆 中点Bresenham
构造函数F(x,y)=x2-y2-R2 对于圆上的点,有F(x,y)=0 对于圆内的点,F(x,y)<0
y
x
3.中点Bresenham画圆 3.中点Bresenham画圆 中点Bresenham
实例
初始值
d0 =1 R =11
初始点 (0,12)
结束点
x >= y
R=12 的1/8 圆弧段的判别式及坐标值
1/8 圆弧离散点的产生
画出对称象素点
离散点对连续点的逼近
Thank you!
计算机图形学实验报告
目录实验一直线的DDA算法一、【实验目的】1.掌握DDA算法的基本原理。
2.掌握DDA直线扫描转换算法。
3.深入了解直线扫描转换的编程思想。
二、【实验内容】1.利用DDA的算法原理,编程实现对直线的扫描转换。
2.加强对DDA算法的理解和掌握。
三、【测试数据及其结果】四、【实验源代码】#include<stdlib.h>#include<math.h>#include<GL/glut.h>#include<stdio.h>GLsizei winWidth=500;GLsizei winHeight=500;void Initial(void){glClearColor(1.0f,1.0f,1.0f,1.0f); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0);}void DDALine(int x0,int y0,int x1,int y1) {glColor3f(1.0,0.0,0.0);int dx,dy,epsl,k;float x,y,xIncre,yIncre;dx=x1-x0; dy=y1-y0;x=x0; y=y0;if(abs(dx)>abs(dy)) epsl=abs(dx);else epsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k<=epsl;k++){glPointSize(3);glBegin(GL_POINTS);glV ertex2i(int(x+0.5),(int)(y+0.5));glEnd();x+=xIncre;y+=yIncre;}}void Display(void){glClear(GL_COLOR_BUFFER_BIT); DDALine(100,100,200,180);glFlush();}void winReshapeFcn(GLint newWidth, GLint newHeight){glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));glClear(GL_COLOR_BUFFER_BIT);winWidth=newWidth;winHeight=newHeight;}int main(int argc,char*argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(400,300);glutInitWindowPosition(100,120);glutCreateWindow("line");Initial();glutDisplayFunc(Display);glutReshapeFunc(winReshapeFcn);glutMainLoop();return 0;}实验二Bresenham绘制直线和圆一、【实验目的】1.掌握Bresenham算法扫描转换圆和直线的基本原理。
计算机图形学实习(实验二)
西北农林科技大学实习报告课程 计算机图形学 学院 理学院 专业年级 信计061 姓名袁金龙学号15206012报告日期2009-5-6实验二 圆的扫描转换算法1.实验目的:了解和掌握中点算法Bresenham 算法。
2.实验步骤:1)对直线、圆弧的几何形状及相对位置进行分析,选定比较合适的算法模型。
2)画出程序流程图; 3)编写程序的源程序; 4)编辑源程序并进行调试;5)进行特殊模式的运行测试,并结合情况进行调整。
6)打印源程序或把源程序以文件的形式提交。
3.实验原理:首先画出的是第一象限内(R R [0,x R 的1/8圆弧,此时中点Bresenham 花圆酸法要从(0,R )到(R R 顺时针地确定最佳逼近于该圆弧的像素序列。
然后根据对称法来画出另七个部分。
(1)输入圆的半径R(2)计算初始值d=1-R,x=0,y=R(3) 绘制点(x,y )及其在八分圆中的另外7个对称点(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);否则结束4.流程图:5.实验内容:1)问题:请用中点Bresenhan画圆算法画出圆心在(-10,10),半径为10的圆 2)正确的图形和交点坐标:图1:圆心在(-10,10),半径为10的圆-150-100-50050100图2:圆心在(-10,10),半径为100的圆3)程序代码:function []=circle(a,b,r)%(a,b)为圆心,r为半径x=0;y=r;d=1-r;while x<=yplot(x+a,y+b,'r+');plot(-x+a,y+b,'r+');plot(-x+a,-y+b,'r+');plot(x+a,-y+b,'r+');m=[x+a,y+b;-x+a,y+b;-x+a,-y+b;x+a,-y+b]plot(y+a,x+b,'r+');plot(-y+a,x+b,'r+');plot(-y+a,-x+b,'r+');plot(y+a,-x+b,'r+');plo t(a,b,'b*')n=[y+a,x+b;-y+a,x+b;-y+a,-x+b;y+a,-x+b]hold on;grid on;if(d<0)d=d+2*x+3;elsed=d+2*(x-y)+5;y=y-1;endx=x+1;end。
计算机图形学 圆的扫描转换
2 中点画圆法
• 理解中点画圆法的基本思想,掌握中点画 圆算法及其特点。
• 能够应用中点画圆法,编程实现画圆的 功能。
3 Bresenham画圆法
•掌握Bresenham画圆算法及其特点。
•能够应用Bresenham画圆法,编程
实现画圆的功能。
第二十三页,共30页。
光栅系统的Bresenham画线算法可通过设定在每 一取样步寻找最接近圆周像素的决策参数而移植为画 圆算法。
MidpointCircle(int r, int color)
{ int x,y; float d; x=0; y=r; d=1.25-r;
drawpixel(x,y,color);
while(x<=y){
if(d<0){ d=d+2*x+3; x++ }
else{d= d+2*(x-y) + 5; x++;y--; }
有如下结论: F(M)< 0 ->M在圆内-> 取P1 F(M)>= 0 ->M在圆外-> 取P2
为此,可采用如下判别式:
P1
M P2
第十一页,共30页。
d = F(M) = F(xp + 1, yp - 0.5)
=(xp
+
2
1)
+
(yp
-
0.5)
2
-
r2
若d<0, 则P1 为下一个象素,那么再下一个象素的判别
•递推关系的确定需根据图分别不同情况进行讨论( 去掉绝对值符号,并进行化简)
(xk , yk )
(xk 1, yk )
(xk 1,yk1)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北京联合大学应用文理学院
实验报告
课程名称计算机图形学
实验(实训)名称圆的扫描转换
班级信息与计算科学2009级姓名学号
同组者
实验(实训)日期完成日期
本实验(实训)所用学时统计
预习实验(实训)报告总计
评阅意见:成绩
北京联合大学应用文理学院
实验报告
一、实验目的
1、掌握用中点画圆法进行圆的扫描转换方法;
2、掌握用Bresenham画圆法进行圆的扫描转换方法;
3、理解中点画圆法与Bresenham画圆法的区别;
二、算法原理介绍
1、中点画圆算法
假设x坐标为xp的各像素点中,与该圆弧最近者已确定,为P(xp,yp),那么,下一个与圆弧最近的像素只能是正右方的P1(xp+1,yp),或右下方的P2
(xp+1,yp-1)两者之一。
令M为P1和P2的中点,易知M的坐标为(xp+1,yp-0.5)。
显然,若M在圆内,则P1离圆弧近,应取为下一个像素;否则应取P2。
判别式d:
d = F(M)=F(xp+1,yp-0.5)=(xp+1)^2+(yp-0.5)^2-R^2
d的初始值为:
d0 = F(1,R-0.5)=1+(R-0.5)^2-R^2=1.25-R
在d≥0的情况下,取右下方像素P2,
d = F(xp+2,yp-1.5)=(xp+2)^2+(yp-1.5)^2-R^2=d+2(xp-yp)+5
在d<0的情况下,取正右方像素P1,
d = F(xp+2,yp-0.5)=(xp+2)^2+(yp-0.5)^2-R^2=d+2xp+3
2、 Bresenham画圆算法
假设生成圆心在坐标原点,半径为r,从x=0到x=y的1/8圆弧。
xi+1=xi +1
相应的y则在两种可能中选择:
y=yi,或者y=yi-1
选择的原则是考察理想的y值是靠近yi还是靠近yi-1
判别式:
d i+1=2(xi+1)2+yi2+(yi-1)2-2r2
判断式d的初始值为:
d0= 3-2r。
如果d i+1>=0,则y=yi-1,
di+2 =d i+1 + 4(xi- yi)+10
如果d i+1<0,则y=yi,
d i+2 =d i+1+ 4x i+6
三、程序源代码
1、中点画圆算法
#include"graphics.h"
#include"math.h"
#include"conio.h"
main()
{
void MidPointCircle(int,int);/*定义主函数变量,MidPointCircle中点画圆算法函数*/
int gdriver,gmode; /*gdriver和gmode分别表示图形驱动器和模式*/
gdriver=DETECT; /*DETECT是自动选择显示模式*/
initgraph(&gdriver,&gmode,"c:\\tc3.0\\BGI");/*图形驱动文件的路径*/ MidPointCircle(200,YELLOW); /*定义圆的半径和颜色*/
getch();/*getch();会等待你按下任意键,再继续执行下面的语句*/
closegraph();/*关闭图形系统*/
return(0); /*返回值为0*/
}
void MidPointCircle(int r,int color) /*定义函数变量半径和颜色*/
{ int x,y;
float d; /*float类型中小数位数为7位,即可精确到小数点后7位 */
x=0; y=r; d=1.25-r;
while(x<y) /*满足条件x<y时进入循环,不满足跳出*/
{ if(d<0)
{d+=2*x+3; x++;}
else { d+=2*(x-y)+5; x++; y--;}
putpixel(x+200,y+200,color); putpixel(y+200,x+200,color);
putpixel(200-x,y+200,color); putpixel(y+200,200-x,color);
putpixel(200+x,200-y,color); putpixel(200-y,x+200,color);
putpixel(200-x,200-y,color); putpixel(200-y,200-x,color);
/* putpixel 在指定位置画一像素*/
}
}
2、 Bresenham画圆算法
#include"graphics.h"
#include"math.h"
#include"conio.h"
main()
{
void Bresenham_Circle(int,int);/* Bresenham_Circle为 Bresenham画圆算法函数*/
int gdriver,gmode;
gdriver=DETECT;
initgraph(&gdriver,&gmode,"c:\\tc3.0\\BGI");
Bresenham_Circle(200,YELLOW); /*定义圆的半径和颜色*/
getch();
closegraph();
return(0);
}
void Bresenham_Circle(int R,int color)
{ int x,y,delta,delta1,delta2,direction;
x=0;
y=R;
delta=2*(1-R);
while(y>=0) /*满足条件y>=0时进入循环,不满足跳出*/
{
putpixel(x+200,y+200,color); putpixel(y+200,x+200,color);
putpixel(200-x,y+200,color); putpixel(y+200,200-x,color);
putpixel(200+x,200-y,color); putpixel(200-y,x+200,color);
putpixel(200-x,200-y,color); putpixel(200-y,200-x,color);
if(delta<0)
{
delta1=2*(delta+y)-1;
if(delta1<=0)direction=1;
else direction=2;
}
else if(delta>0)
{
delta2=2*(delta-x)-1;
if(delta2<=0) direction=2;
else direction=3;
}
else
direction=2;
switch (direction)/*switch语句,即“切换”语句;case即“情况*/ {
case 1:x++;
delta+=2*x+1;
break;/*执行 break 语句会退出当前循环或语句*/
case 2:x++;
y--;
delta+=2*(x-y+1);
break;
case 3: y--;
delta+=(-2*y+1);
break;
}
}
}
四、实验结果
图1中点画圆算法生成的圆
半径r=200,颜色为黄色
图2 Bresenham画圆算法生成的圆
半径R=200,颜色为黄色
五、总结与体会
通过运用 C 语言环境下的图像显示设置,本次实验我学会了用中点画圆法、Bresenham 画圆法进行圆的扫描转换,更加深刻的理解了中点画圆法、Bresenham 画圆法进行圆的扫描转换的生成原理。
掌握了中点画圆、Bresenham画圆算法及其特点。
能够应用中点画圆算法、Bresenham画圆算法,编程实现画圆的功能。
六、参考文献
1、计算机图形学
2、C语言。