计算机图形学画圆的程序
- 格式:doc
- 大小:192.00 KB
- 文档页数:4
画圆环算法c程序全文共四篇示例,供读者参考第一篇示例:画圆环是计算机图形学中常见的基本图形之一,常用于游戏开发、动画制作等领域。
在计算机中,画圆环的算法有多种,其中最常用的是中点画圆算法。
本文将介绍使用C语言实现中点画圆算法的程序,并进行详细分析和讲解。
1. 算法原理中点画圆算法是一种简单而高效的算法,其基本原理是通过逐渐逼近圆形的方法,利用对称性和中点的位置进行迭代计算。
具体步骤如下:(1)给定圆的半径r和圆心坐标(x0, y0),设置初始点P(0, r)作为起点,并计算判别式d=1-r。
(2)在每次迭代中,分别取直线y=x和y=-x两侧的中点,分别计算两种情况下的判别式值,并根据判别式值的大小决定下一个中点的位置。
(3)重复进行上述步骤,直到计算完整个圆的一周。
2. C程序实现下面是使用C语言实现中点画圆算法的程序代码:```c#include <stdio.h>#include <graphics.h>void plot_circle_points(int x0, int y0, int x, int y) { // 绘制圆的八个对称点putpixel(x0 + x, y0 + y, WHITE);putpixel(x0 - x, y0 + y, WHITE);putpixel(x0 + x, y0 - y, WHITE);putpixel(x0 - x, y0 - y, WHITE);putpixel(x0 + y, y0 + x, WHITE);putpixel(x0 - y, y0 + x, WHITE);putpixel(x0 + y, y0 - x, WHITE);putpixel(x0 - y, y0 - x, WHITE);}void midpoint_circle(int x0, int y0, int r) { int x = 0, y = r;int d = 1 - r;plot_circle_points(x0, y0, x, y); while (x < y) {if (d < 0) {d = d + 2 * x + 3;x++;} else {d = d + 2 * (x - y) + 5;x++;y--;}plot_circle_points(x0, y0, x, y);}}delay(5000);closegraph();return 0;}```以上是一个简单的使用C语言实现中点画圆算法的程序代码。
实验三:圆的生成算法的实现班级 08信计2 学号 64 姓名刘辉分数一、实验目的和要求1.理解圆生成的基本原理,掌握几种常见的圆生成算法。
2.利用Visual C++ 实现圆生成的中点画圆的算法。
3.利用Visual C++ 实现圆的Bresenham算法。
4.简单了解其他算法。
二、实验内容:1.利用中点画图算法,在屏幕上生成任意一段圆弧。
2.利用图的对称性,将(1)题生成的圆弧扩展为一个整圆。
3.利用bresebham算法设计出一段圆弧。
三、实验步骤:1.预习教材关于圆的生成原理。
2.仿照教材关于圆生成的中点画圆算法和bresenham算法,使用C++实现该算法。
3.调试、编译、运行程序。
利用bresenham算法生成圆的代码:#include<graphics.h>#include<stdio.h>#include<conio.h>void BresenhemCircle(int centerx, int centery, int radius, int color, int type);void main(){int drive=DETECT,mode;int i,j;initgraph(&drive,&mode,"");BresenhemCircle(300,200,100,150,0);getch();closegraph();}void BresenhemCircle(int centerx, int centery, int radius, int color, int type) {int x =type = 0;/*初始横坐标为原点*/int y = radius; /*初始纵坐标远离原点*/int delta = 2*(1-radius);int direction;while (y >= 0){getch();if (!type)/*执行*/{/*在上半圆画两点*/putpixel(centerx+x, centery+y, color);putpixel(centerx-x, centery+y, color);/*在下半圆画两点*/putpixel(centerx-x, centery-y, color);putpixel(centerx+x, centery-y, color);getch();}else{line(centerx+x, centery+y, centerx+x, centery-y); line(centerx-x, centery+y, centerx-x, centery-y); getch();}if (delta < 0){if ((2*(delta+y)-1) < 0)direction = 1;elsedirection = 2;}else if(delta > 0){if ((2*(delta-x)-1) > 0)direction = 3;elsedirection = 2;}elsedirection=2;switch(direction){case 1:x++;delta += (2*x+1); break;case 2:x++;y--;delta += 2*(x-y+1); break;case 3:y--;delta += (-2*y+1); break;}}}实验结果:四、实验结果分析:Bresenham画圆算法是最有效的算法之一,通过画出八分之一的圆周,对称得到整个圆周,第一想先的图形,让X轴量平均增加,通过选择理想的Y轴坐标,确定得到整个图形,算法的实现简单,且时间复杂度较低。
C语言画图实验代码,包含画直线,画圆,椭圆#include "graphics.h"#include "conio.h"#include "dos.h"#include "math.h"#include "stdio.h"/* 直线中点算法*/void midpointline(int x0,int y0,int x1,int y1,int color ) {int x,y;int a,b,c,d,d1,d2;a=(y0-y1);b=(x1-x0);d=a+a+b;d1=a+a;d2=a+b+a+b;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);}}/* 直线DDA算法*/DDA_line(int x1,int y1,int x2,int y2,int color) {int i;float increx,increy,x,y,length,xx,yy;if(abs(x2-x1)>abs(y2-y1))length=abs(x2-x1);elselength=abs(y2-y1);increx=(x2-x1)/length;increy=(y2-y1)/length;x=x1;y=y1;for(i=1;i<=length;i++)yy=y+0.5;putpixel((int)xx,(int)yy,color);x=x+increx;y=y+increy;}}/* 椭圆中点算法*/void MidBresenhamllipse(double a,double b,int color) { double x,y, d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);putpixel(x+300,y+200,color); putpixel(-x+300,-y+200,color); putpixel(-x+300,y+200,color); putpixel(x+300,-y+200,color); while(b*b*(x+1)<a*a*(y-0.5)) {if(d1<=0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*((-2)*y+2); x++;y--;}putpixel(x+300,y+200,color);putpixel(-x+300,-y+200,color);putpixel(-x+300,y+200,color);putpixel(x+300,-y+200,color);}d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b; while(y>0){{d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x+300,y+200,color);putpixel(-x+300,-y+200,color);putpixel(-x+300,y+200,color);putpixel(x+300,-y+200,color);}}/* 参数法画椭圆*/void cs_ellipse(int x0,int y0,int a,int b,int dt) {int x,y,n,i;float t=0,t1;t1=dt*0.0174533;n=360/dt;moveto(x0+a,y0);for(i=1;i<n;i++){t=t+t1;x=x0+a*cos(t);y=y0+b*sin(t);lineto(x,y);}lineto(x0+a,y0);}void cs_Ellipse(int x0,int y0,int a1,int b1,int color1) { int i,x=x0,y=y0,a=a1,b=b1,color=color1;cs_ellipse(x,y,a,b,1);}/* 中点Bresenham算法画圆*/void BresenhemCircle(int x0,int y0,double r,int color) {int x,y,d;x=0;y=(int)r;d=(int)(3-2*r);while(x<y){cirpot(x0,y0,x,y,color);if(d<0)d+=4*x+6;else{d+=4*(x-y)+10;y--;}x++;}if(x==y)cirpot(x0,y0,x,y,color);}int cirpot(int x0,int y0,int x,int y,int color){putpixel((x0+x),(y0+y),color);putpixel((x0+y),(y0+x),color);putpixel((x0+y),(y0-x),color);putpixel((x0+x),(y0-y),color);putpixel((x0-x),(y0-y),color);putpixel((x0-y),(y0-x),color);putpixel((x0-y),(y0+x),color);putpixel((x0-x),(y0+y),color);return(0);}/* 参数法画圆*/void cs_circle(int x0,int y0,int r,int dt) {int x,y,n,i;float t=0,t1;t1=dt*0.0174533;n=360/dt;moveto(x0+r,y0);for(i=1;i<n;i++){t=t+t1;x=x0+r*cos(t);y=y0+r*sin(t);lineto(x,y);}lineto(x0+r,y0);}void cs_Circle(int x0,int y0,int r1,int color1) {int i,x=x0,y=y0,r=r1,color=color1;cs_circle(x,y,r,1);}void fun(){printf("*********************************************************** *\n");printf("* input '1' ues midpointline painting line ! *\n");printf("* input '2' ues DDA_line painting line! *\n");printf("* input '3' ues system function painting line ! *\n");printf("* input '4' ues midBresenham painting elliptic ! *\n");printf("* input '5' ues parametric painting elliptic ! *\n");printf("* input '6' ues system function painting elliptic ! *\n");printf("* input '7' ues midBresenham painting circle ! *\n");printf("* input '8' ues midBresenham painting circle ! *\n");printf("* input '9' ues parametric painting circle ! *\n");printf("* input 'a' print all graphics!!! *\n");printf("* input 'E' exit system! *\n");printf("*********************************************************** *\n"); }/*主函数块*/void main(){int gdriver=DETECT,gmode;/*setbkcolor(9);*/char c;initgraph(&gdriver,&gmode,"c:\tc");fun();scanf("%c",&c);do{switch(c){case '1': midpointline(120,220,200,160,20);break; case '2': DDA_line(110,120,200,340,10);break; case '3': line(110,120,200,240);break;case '4': MidBresenhamllipse(34,55,6);break;case '5': cs_Ellipse(120,240,20,120,21);break; case '6': ellipse(110,250,0,360,100,40);break;case '7': BresenhemCircle(100,100,50,4);break; case '8': circle(100,100,67);break;case '9': cs_Circle(100,100,23,2);break;case 'a': midpointline(120,220,200,160,20); DDA_line(110,120,200,340,10);line(110,120,200,240);MidBresenhamllipse(34,55,6);cs_Ellipse(120,240,20,120,21);ellipse(110,250,0,360,100,40); BresenhemCircle(100,100,50,4);circle(100,100,67);cs_Circle(100,100,23,2);break;}printf("input any key to continue!!!!\n"); getch();cleardevice();fun();scanf("%c",&c);}while(c!='E');printf("exit system!\n"); closegraph();}。
浙江大学城市学院实验报告课程名称计算机图形学实验项目名称画圆方法实验成绩指导老师(签名)日期一. 实验目的和要求通过实验加深对Bresenham圆生成算法的理解。
二. 实验内容和原理(1)数据输入项(或者函数参数)为:圆心坐标与半径(2)输出圆。
三. 实验设计与分析Besenham圆①创建一个application,将其全部保存,②双击划圆按扭,定义参数如下:x,y,x0,y0,r,direction : integer;delta,delta1,delta2 : integer;color1 : integer;③编写代码如下if self.Edit1.Text = '' thenbeginApplication.MessageBox('圆心坐标X没有输入!','提示',0);abort;endelse if self.Edit2.Text = '' thenbeginApplication.MessageBox('圆心坐标Y没有输入!','提示',0);abort;endelse if self.Edit3.Text = '' thenbeginApplication.MessageBox('圆半径没有输入!','提示',0);abort;endelsex0:= strtoint(Edit1.Text);y0:=strtoint(Edit2.Text);r:=strtoint(Edit3.Text);x:=0;y:=r;delta:=2*(1-r);color1:= clGreen;while y>=0 dobeginimage1.canvas.Pixels[x0+x,y0+y]:=color1;image1.canvas.Pixels[x0-x,y0+y]:=color1;image1.canvas.Pixels[x0+x,y0-y]:=color1;image1.canvas.Pixels[x0-x,y0-y]:=color1;if delta<0 thenbegindelta1:=2*(delta+y)-1;if delta1<=0 then direction:=1else direction:=2;endelse if delta>0 thenbegindelta2:=2*(delta-x)-1;if delta2<=0 then direction:=2else direction:=3;endelsedirection:=2;case direction of1 : begininc(x);delta:=delta+2*x+1;end;2 : begininc(x);dec(y);delta:=delta+2*(x-y+1);end;3 : begindec(y);delta:=delta+(-2*y+1);end;end;end;end;④双击演示按扭,定义参数如下:x,y,x0,y0,r,direction : integer;delta,delta1,delta2 : integer;color1 : integer;⑤编写代码如下if self.Edit1.Text = '' thenbeginApplication.MessageBox('圆心坐标X没有输入!','提示',0);abort;endelse if self.Edit2.Text = '' thenbeginApplication.MessageBox('圆心坐标Y没有输入!','提示',0);abort;endelse if self.Edit3.Text = '' thenbeginApplication.MessageBox('圆半径没有输入!','提示',0);abort;endelsex0:= strtoint(Edit1.Text);y0:=strtoint(Edit2.Text);r:=strtoint(Edit3.Text);x:=0;y:=r;delta:=2*(1-r);color1:= clGreen;while y>=0 dobeginimage1.canvas.Pixels[x0+x,y0+y]:=color1;image1.canvas.Pixels[x0-x,y0+y]:=color1;image1.canvas.Pixels[x0+x,y0-y]:=color1;image1.canvas.Pixels[x0-x,y0-y]:=color1;if delta<0 thenbegindelta1:=2*(delta+y)-1;if delta1<=0 then direction:=1else direction:=2;endelse if delta>0 thenbegindelta2:=2*(delta-x)-1;if delta2<=0 then direction:=2else direction:=3;endelsedirection:=2;case direction of1 : begininc(x);delta:=delta+2*x+1;end;2 : begininc(x);dec(y);delta:=delta+2*(x-y+1);end;3 : begindec(y);delta:=delta+(-2*y+1);end;end;end;⑥双击退出按扭,编写代码如下:Close;⑦双击清屏按扭,编写代码如下:image1.Canvas.Brush.Color:=clwhite;image1.Canvas.FillRect(Rect(0,0,350,250));Form3.Edit1.Clear;Form3.Edit2.Clear;Form3.Edit3.Clear;⑧保存,完成。
#include<windows.h>#include<gl/glut.h>#include"stdio.h"int m_PointNumber = 0; //动画时绘制点的数目int m_DrawMode = 1; //绘制模式 1 DDA算法画直线// 2 中点Bresenham算法画直线// 3 改进Bresenham算法画直线// 4 八分法绘制圆// 5 四分法绘制椭圆//绘制坐标线void DrawCordinateLine(void){int i = -250 ;//坐标线为黑色glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=-250;i<=250;i=i+10){glVertex2f((float)(i), -250.0f);glVertex2f((float)(i), 250.0f);glVertex2f(-250.0f, (float)(i));glVertex2f(250.0f, (float)(i));}glEnd();}//绘制一个点,这里用一个正方形表示一个点void putpixel(GLsizei x, GLsizei y){glRectf(10*x,10*y,10*x+10,10*y+10);}/////////////////////////////////////////////////////////////////////DDA画线算法 //// //// //// /////////////////////////////////////////////////////////////////////void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {//设置颜色glColor3f(1.0f,0.0f,0.0f);//对画线动画进行控制if(num == 1)printf("DDA画线算法:各点坐标\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,epsl,k;GLfloat 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 / epsl ;yIncre = (float)dy / epsl ;for(k = 0; k<=epsl; k++){putpixel((int)(x+0.5), (int)(y+0.5));if (k>=num-1) {printf("x=%f , y=%f,取整后 x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));break;}x += xIncre;y += yIncre;if(x >= 25 || y >= 25) break;}}/////////////////////////////////////////////////////////////////////中点Bresenham算法画直线(0<=k<=1) //// //// //// /////////////////////////////////////////////////////////////////////void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("中点Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;GLfloat UpIncre,DownIncre,x,y,d,k,dx,dy;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}if(k>1){d=dy-2*dx;UpIncre=2*dy-2*dx;DownIncre=-2*dx;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}if(k<0&&k>=-1){d=dx-2*dy;UpIncre=-2*dy;DownIncre=-2*dx-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d>0){y--;d+=DownIncre;}else d+=UpIncre;}}if(k<-1){d=-dy-2*dx;UpIncre=-2*dx-2*dy;DownIncre=-2*dx;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}}/////////////////////////////////////////////////////////////////////改进的Bresenham算法画直线(0<=k<=1) //// //// x1,y1 终点坐标 //// /////////////////////////////////////////////////////////////////////void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei x,y,dx,dy,e,k;if(num == 1)printf("改进的Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}if(k>1){e=-dy;x=x0;y=y0;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;e=e+2*dx;if(e>0){x++;e=e-2*dy;}}}if(k<0&&k>=-1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e<0){y--;e=e+2*dx;}}}if(k<-1){e=-dy;x=x0;y=y0;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;e=e-2*dx;if(e<0){x++;e=e-2*dy;}}}}///////////////////////////////////////////////////////////Bresenham算法画圆 //// //// //// ///////////////////////////////////////////////////////////void CirclePoint(GLsizei x,GLsizei y){ putpixel(x,y);putpixel(x,-y);putpixel(y,-x);putpixel(-y,-x);putpixel(-x,-y);putpixel(-x,y);putpixel(-y,x);putpixel(y,x);}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei R, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei d;x=0;y=R;d=1-R;if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");else if(num==0)return;while(x<=y){CirclePoint(x,y);if (x>=num-1) {printf("x=%d,y=%d,d=%d\n", x, y,d);break;}if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}void Bresenham2Circle(GLsizei a,GLsizei b,GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num==1)printf("Bresenham算法画椭圆:各点坐标及判别式的值\n");else if(num==0)return;GLsizei x,y;float d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.5);putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);while(b*b*(x+1)<a*a*(y-0.5)){if (x>=num-1) {printf("x=%d,y=%d,d1=%d\n", x, y,d1);break;}if(d1<=0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}//while上半部分d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while(y>0){if (x>=num-1) {printf("x=%d,y=%d,d2=%d\n", x, y,d2);break;}if(d2<=0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}}//初始化窗口void Initial(void){// 设置窗口颜色为蓝色glClearColor(0.0f, 0.0f, 1.0f, 1.0f);}// 窗口大小改变时调用的登记函数void ChangeSize(GLsizei w, GLsizei h){if(h == 0) h = 1;// 设置视区尺寸glViewport(0,0, w, h);// 重置坐标系统glMatrixMode(GL_PROJECTION);glLoadIdentity();// 建立修剪空间的范围if (w <= h)glOrtho (-250.0f, 250.0f, -250.0f, 250.0f*h/w, 1.0, -1.0);elseglOrtho (-250.0f, 250.0f*w/h, -250.0f, 250.0f, 1.0, -1.0);}// 在窗口中绘制图形void ReDraw(void){//用当前背景色填充窗口glClear(GL_COLOR_BUFFER_BIT);//画出坐标线DrawCordinateLine();switch(m_DrawMode){case 1:DDACreateLine(0,0,20,15,m_PointNumber);break;case 2:BresenhamLine(0,0,-20,15,m_PointNumber);break;case 3:Bresenham2Line(1,1,8,6,m_PointNumber);break;case 4:BresenhamCircle(0,0,20,m_PointNumber);break;case 5:Bresenham2Circle(10,8,m_PointNumber);default:break;}glFlush();}//设置时间回调函数void TimerFunc(int value){if(m_PointNumber == 0)value = 1;m_PointNumber = value;glutPostRedisplay();glutTimerFunc(500, TimerFunc, value+1);}//设置键盘回调函数void Keyboard(unsigned char key, int x, int y) {if (key == '1') m_DrawMode = 1;if (key == '2') m_DrawMode = 2;if (key == '3') m_DrawMode = 3;if (key == '4') m_DrawMode = 4;if (key == '5') m_DrawMode = 5;m_PointNumber = 0;glutPostRedisplay();}//void main(void)int main(int argc, char* argv[]){glutInit(&argc, argv);//初始化GLUT库OpenGL窗口的显示模式glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600,600);glutInitWindowPosition(100,100);glutCreateWindow("基本图元绘制程序);glutDisplayFunc(ReDraw);glutReshapeFunc(ChangeSize);glutKeyboardFunc(Keyboard);//键盘响应回调函数glutTimerFunc(500, TimerFunc, 1);// 窗口初始化Initial();glutMainLoop(); //启动事件处理循环return 0;}。