中点画圆法的扫描转换算法

合集下载

{实用}直线圆的各种插补算法

{实用}直线圆的各种插补算法

第四章、基本图形生成算法教学目的:1、知道图形生成中的基本问题;2、熟练掌握直线的扫描转换、圆与椭圆的扫描;3、掌握区域填充;4、了解线宽与线型的处理。

�在光栅显示器上显示的任何一种图形,实际上都是一些具有一种或多种颜色的象素的集合。

�生成算法即图形设备生成图形的方法,也叫光栅化或或图形的扫描转换,是确定一个象素集合及其颜色,用于显示一个图形的过程。

确定一个象素集合及其颜色,用于显示一个图形的过程,称为图形的扫描转换或光栅化。

�对图形的扫描转换分为两部分:先确定像素,再用图形的颜色或其他属性进行某种写操作。

绘图元素�构成图形的基本元素,主要有点、直线、圆和曲线等。

图形元素包含的信息:①图元的类型②图元的几何信息③图元的非几何信息;④图元的指针信息11、点22、位置33、像素44、直线55、曲线66、填充点、线图形基元包括:多边形、曲线、字符串 实心图形(或称图形填充)一级图形元素二级图形元素第一节、扫描转换算法一、坐标系1.用户坐标系�在实际世界中用来描述物体的位置、形状等。

坐标单位任意,坐标值是实数、范围不限。

2.笛卡尔坐标系(直角坐标系)�在计算机图形学中使用用来描述物体。

3.设备坐标系�在某一特定设备上用来描述物体,如显示器的屏幕坐标系,绘图仪的绘图坐标系。

坐标单位为像素、步长,即设备的分辨率。

坐标值是整数,有固定的取值范围。

4.规范坐标系�在通用图形软件包中使用的用来描述物体数据所采用的坐标系。

�目的是为了使通用图形软件包摆脱对具体物理设备的依赖性,也为了便于在不同应用和不同系统之间交换图形信息。

�坐标单位任意取,坐标取值范围是[0,1]区间。

笛卡儿坐标系与屏幕坐标系的转换�屏幕(x,y)=(x笛卡儿+x最大分辨率/2,y最大分辨率/2- y笛卡儿)二、笛卡尔坐标系和设备坐标系中相关概念的区别(1)像素点�·在几何学中,点没有准数,没有大小,只表示了在坐标系统中的一个位置。

·在图形系统中,点要由数值坐标表示。

圆的扫描转换原理

圆的扫描转换原理
确定当前点 ( , )后,可通过 ( , )的值来决定下一个点 :
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。

计算机图形学习题解答

计算机图形学习题解答
当 b2 xi 0.5 p a2 yi 1 时转入上半部分。
初始值 d2用下半部分计算的最后像素点的坐标值来计算。
已知椭圆的长半轴a=12,b=8.用中点Bresenham画椭圆算法 确定第二象限椭圆弧上的像素点的位置,初始点为(-12,0).
解: 根据题意,先绘制椭圆弧的下半部分. y是最大位移方向,每次走一步,在y方向上加1,x方向上加1或加0. 构造判别式:
(4)d的初始值
d0
F
R 0.5, 2
R 2
1
1.25
2R 2
5.9解: 根据题意,算法要从点(a,0)到(0,b)逆时针确定第一象限椭圆弧。
先绘制椭圆弧的下半部分.
y是最大位移方向,每次走一步,在y方向上加1,x方向上减1或0.
构造判别式:
d1 F (xi 0.5, yi 1) b2 (xi 0.5)2 a2 ( yi 1)2 a2b2
4 2 2
45 2 2
1 1
5-2 2 4-2 2 1
(2)
1 0 0 0 1 0 1 0 0 0 1 0
T2
0
1 0 • 1 0 0 • 0 1 0 1 0 0
5 4 1 0 0 1 5 4 1 9 -1 1
4 1 1
8 3 1
7 3 1 • T2= 6 6 1
7 7 1
2 6 1
当d1 0时 d1 F (xi 0.5, yi 2) b2 (xi 0.5)2 a2 ( yi 2)2 a2b2 d1 a2 (2 yi 3) d1 288yi 432
d1的初始值:d1 F 11.5,1 608
下面绘制椭圆弧的上半部分. x是最大位移方向,每次走一步,在x方向上加1,y方向上加1或加0. 构造判别式:

圆的扫描生成算法原理

圆的扫描生成算法原理

圆的扫描转换一、算法原理本节主要讲解仅包含加减操作的顺时针绘制1/8圆的中点Bresenham 算法原理。

1、圆的特性圆心在原点、半径为R 的圆方程的隐函数表达式为:圆将平面划分成三个区域:对于圆上的点,F(x ,y)=0;对于圆外的点,F (x ,y )>0;对于圆内的点,F (x ,y )<0。

事实上,考虑到圆在第一象限内的对称性,本算法可以进一步简化。

因为AC 段圆弧和CB 段圆弧以对称轴x =y 完全对称,如图3-6所示,所以可以用四条对称轴x =0,y =0, x =y,x =-y 把圆分成8等份。

只要绘制出第一象限内的1/8圆弧Ⅰ,根据对称性就可绘制出整圆,这称为八分法画圆算法。

假定第一象限内的任意点为P (x,y ),可以顺时针确定另外7个点:P (y ,x )P (y ,-x ),P (x,- y ) ,P (-x ,-y ),P (-y ,-x ),P (-y ,x ),P (-x ,y )。

),(222=-+=R y x y x F从P (xi ,yi )开始,为了进行下一像素点的选取,需将Pu 和Pd 的中点M (x i +1,y i -0.5)代入隐函数,构造中点偏差判别式:当d<0时,中点M 在圆内,下一像素点应点亮Pu ,即y 方向不退步;当d>0时,中点M 在圆外,下一像素点应点亮Pd ,即y 方向退一步;当d =0时,中点M 在圆上, Pu 、Pd 和圆的距离相等,点亮Pu 或Pd 均可,约定取Pd 。

因此,2、递推公式1.中点偏差判别式的递推公式现在如果考虑主位移方向再走一步,应该选择哪个中点代入中点偏差判别式以决定下一步应该点亮的像素,分两种情况讨论。

222)5.0()1()5.0,1(),(R y x y x F y x F d i i i i M M --++=-+==⎩⎨⎧≥<=+)0( 1-)0( 1d y d y y i i i中点偏差判别式的递推2.中点偏差判别式的初始值圆的起点为P0(0,R ),x 为主位移方向。

圆弧扫描转换

圆弧扫描转换
P(Xp ,Yp ) P1 M P2
2 2 2
M=(Xp+1,Yp-0.5)
20
中点画圆法基本思想
d = F(M) = F(xp + 1, yp - 0.5) 2 2 2 =(xp + 1) + (yp - 0.5) - R 若d>=0, 则P2(xp + 1, yp – 1) 为下一个象素,那么: d1 = F(xp + 2, yp - 1.5) = d + (2xp + 3)+(-2 yp + 2) 若d<0, 则P1(xp + 1, yp ) 为下一个象素,那么: d2 = F(xp + 2, yp - 0.5)= d + 2xp +3
F(M)< 0则M在圆内-> 取P1 F(M)>= 0 则M在圆外-> 取P2 P(Xp ,Yp ) P1 M P2
第一象限靠近y轴的八 分之一圆
19
中点画圆法基本思想
F(X,Y)=X + Y - R ,有如下结论:
F(M)< 0 ->M在圆内-> 取P1 F(M)>= 0 ->M在圆外-> 取P2
= yi + 2 − k ( xi + 0.5) − b = di − k
5
复习:中点画线法步骤
1.输入直线的两端点P0(x0,y0)和P1(x1,y1)。 2.计算初始值△x、△y、d=0.5-k、x=x0、y=y0; 3.绘制点(x,y)。判断d的符号; 4.若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1k;否则(x,y)更新为(x+1,y),d更新为d-k。 5.当直线没有画完时,重复步骤3。否则结束

计算机图形学之扫描转换线画图元的方法

计算机图形学之扫描转换线画图元的方法

扫描转换线画图元实验目的:通过上机实践,在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>即可出现连续的椭圆图象。

扫描转换算法——DDA、中点画线画圆、椭圆

扫描转换算法——DDA、中点画线画圆、椭圆

扫描转换算法——DDA、中点画线画圆、椭圆我的理解:在光栅图形学中,由于每⼀个点的表⽰都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表⽰。

数值微分法(DDA):以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:import matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':x0, y0, x1, y1 = map(int, input("请输⼊直线的起点与终点: ").split('')) ax = subplot(title='DDA');ax.plot([x0, x1], [y0, y1], 'r');delta_x = x1-x0;delta_y = y1-y0;#画坐标轴if x1>y1:ax.axis([x0-1, x1+1, y0-1, x1+1]);init(ax);else:ax.axis([x0-1, y1+1, y0-1, y1+1]);init(ax);#计算斜率k的值if delta_x == 0:k = 999999999;else:k = delta_y / delta_x;#如果|k|<=1if k>-1 and k<1:while x0<=x1:x = round(x0);y = round(y0);ax.plot(x, y, 'b.');x0 += 1;y0 = y0+k;else:while y0<=y1:x = round(x0);y = round(y0);ax.plot(x, y, 'b.');x0 += 1/k;y0 += 1;plt.show();运⾏截图:中点画线:以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:wimport matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':x0, y0, x1, y1 = map(int, input("请输⼊直线的起点与终点: ").split('')) ax = subplot(title='Midpoint');ax.plot([x0, x1], [y0, y1], 'r');a = y0-y1;b = x1-x0;d = 2*a+b;d1 = 2*a;d2 = 2*(a+b);#画坐标轴if x1>y1:ax.axis([x0-1, x1+1, y0-1, x1+1]);init(ax);else:ax.axis([x0-1, y1+1, y0-1, y1+1]);init(ax);x = x0;y = y0;ax.plot(x, y, 'r.');while(x < x1):if d<0:x += 1;y += 1;d += d2;else:x += 1;d += d1;ax.plot(x, y, 'r.');plt.show()中点画圆法:以下PPT截图来⾃北京化⼯⼤学李辉⽼师import matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom pylab import *def init(ax):#将主标签设置为1的倍数majorLocator = MultipleLocator(1);#设置主刻度标签的位置,标签⽂本的格式ax.xaxis.set_major_locator(majorLocator);ax.yaxis.set_major_locator(majorLocator);ax.grid(True);if__name__ == '__main__':r = int(input("请输⼊半径: "));plt.figure(figsize=(r*0.1, r*0.1));ax = subplot(title='MidPointCircle');d = 1-r;ax.axis([-r-1, r+1, -r-1, r+1]);init(ax);x = 0;y = r;ax.plot(x, y, 'r.');while(x <= y):if d<0:d += 2*x+3;else:d += 2*(x-y)+5;y -= 1;x += 1;ax.plot(x, y, 'r.');ax.plot(y, x, 'r.');ax.plot(x, -y, 'r.');ax.plot(-y, x, 'r.');ax.plot(-x, y, 'r.');ax.plot(y, -x, 'r.');ax.plot(-x, -y, 'r.');ax.plot(-y, -x, 'r.');plt.show()椭圆的扫描转换:以下PPT截图来⾃北京化⼯⼤学李辉⽼师代码实现:import matplotlib.pyplot as pltimport matplotlib.patches as patchesimport mpl_toolkits.axisartist as axisartistfrom pylab import *def init(ax):#设置x轴:空⼼箭头、数值在下⽅ax.axis["x"] = ax.new_floating_axis(0, 0);ax.axis["x"].set_axisline_style("->", size = 1.0);ax.axis["x"].set_axis_direction("bottom");#设置y轴:空⼼箭头、数值在右⽅ax.axis["y"] = ax.new_floating_axis(1, 0);ax.axis["y"].set_axisline_style("->", size = 1.0);ax.axis["y"].set_axis_direction("right");if__name__ == '__main__':a, b = map(int, input("请输⼊椭圆的长、短半径: ").split('')); fig = plt.figure(figsize=(5, 7))#初始化画布ax = axisartist.Subplot(fig, 111, title='MidpointElipse');#将绘图区对象添加到画布中fig.add_axes(ax)init(ax);x = 0;y = b;d1 = b*b+a*a*(-b+0.25); #增量初值ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');while(b*b*(x+1)<a*a*(y-0.5)): #法向量的x、y不⼀样⼤时if d1<0:d1 += b*b*(2*x+3);x += 1;else:d1 += b*b*(2*x+3)+a*a*(-2*y+2);x += 1;y -= 1;#画四个对称点ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');ax.plot(-x, y, 'r.');ax.plot(-x, -y, 'r.');#画到了法向量的x=y,即椭圆弧的下半部分d2 = b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while y>0: #终结条件y>0if d2<0:d2 += b*b*(2*x+2)+a*a*(-2*y+3);x += 1;y -= 1;else:d2 += a*a*(-2*y+3);y -= 1;ax.plot(x, y, 'r.');ax.plot(x, -y, 'r.');ax.plot(-x, y, 'r.');ax.plot(-x, -y, 'r.');plt.show()。

中点画圆法的扫描转换算法

中点画圆法的扫描转换算法
实验报告
专业:软件工程班级:学号:姓名:
课程名称:计算机图形图像处理基础2016– 2017年度第2学期
课程类别:专业必修实验时间:2017年月日
实验名称:中点画圆法的扫描转换算法
实验软硬件要求:Windows7 , Windows XP等都可,
使用MyEclipse做实验。
实验目的和要求:
编写中点画圆法的扫描转换程序
实验内容:见附页
实验总结以及心得体会:通过这次自己动手作程序,加深了对以往所学知识的了解和应用。把老师讲的东西,通过自己的努力和探索并加以研究,变成自己所能理解的东西截图如下:
主要代码:
1.编写主界面程序,且确定原点的坐标和半径
2.赋值x0.y0,x,y,r
3.编写中点画圆法的扫描转换算法画圆
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验内容:见附页
实验总结以及心得体会:通过这次自己动手作程序,加深了对以往所学知识的了解和应用。把老师讲的东西,通过自己的努力和探索并加以研究,变成自己所能理解的东西。
评定成绩:写主界面程序,且确定原点的坐标和半径
2.赋值x0.y0,x,y,r
3.编写中点画圆法的扫描转换算法画圆
实验报告
专业:软件工程班级:学号:姓名:
课程名称:计算机图形图像处理基础2016– 2017年度第2学期
课程类别:专业必修实验时间:2017年月日
实验名称:中点画圆法的扫描转换算法
实验软硬件要求:Windows7 , Windows XP等都可,
使用MyEclipse做实验。
实验目的和要求:
编写中点画圆法的扫描转换程序
相关文档
最新文档