计算机图形学 圆周算法的实现
画圆环算法c程序

画圆环算法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语言实现中点画圆算法的程序代码。
【计算机图形学】基本图形元素:圆的生成算法

【计算机图形学】基本图形元素:圆的⽣成算法圆的特征圆被定义为到给定中⼼位置(xc,yc)距离为r的点集。
圆⼼位于原点的圆有四条对称轴x=0,y=0, x=y和x=-y。
若已知圆弧上⼀点(x,y),可以得到其关于四条对称轴的其它7个点,这种性质称为⼋分对称性。
因此,只要扫描转换⼋分之⼀圆弧,就可以求出整个圆弧的象素集。
显⽰圆弧上的⼋个对称点的算法:void CirclePoints(int x,int y,int color){ Putpixel(x,y,color); Putpixel(y,x,color);Putpixel(-x,y,color); Putpixel(y,-x,color);Putpixel(x,-y,color); Putpixel(-y,x,color);Putpixel(-x,-y,color); Putpixel(-y,-x,color);}中点画圆算法果我们构造函数 F(x,y)=x2+y2-R2,则对于圆上的点有F(x,y)=0,对于圆外的点有F(x,y)>0,对于圆内的点F(x,y)<0 。
与中点画线法⼀样,构造判别式:d=F(M)=F(xp+1,yp-0.5)=(xp+1)2+(yp-0.5)2-R2若 d<0,则应取P1为下⼀象素,⽽且再下⼀象素的判别式为:d=F(xp+2,yp-0.5)=(xp+2)2+(yp-0.5)2-R2=d+2xp+3若d≥0,则应取P2为下⼀象素,⽽且下⼀象素的判别式为d=F(xp+2,yp-1.5)=(xp+2)2+(yp-1.5)2-R2=d+2(xp-yp)+5我们这⾥讨论的第⼀个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R【算法流程图】【算法代码】void PaintArea::drawCircleMiddle(QPainter &painter,const QPoint ¢er, int r) {int x,y,deltax,deltay,d;x=0;y=r;deltax=3;deltay=2-3-3;d=1-r;while(x<y){if(d<0){d+=deltax;deltax+=2;x++;}else{d+=(deltax+deltay);deltax+=2;deltay+=2;x++;y++;}painter.drawPoint(center.x()+x,center.y()+y);painter.drawPoint(center.x()+x,center.y()-y);painter.drawPoint(center.x()-x,center.y()+y);painter.drawPoint(center.x()-x,center.y()-y);painter.drawPoint(center.x()+y,center.y()+x);painter.drawPoint(center.x()+y,center.y()-x);painter.drawPoint(center.x()-y,center.y()+x);painter.drawPoint(center.x()-y,center.y()-x);}}Bresenham画圆算法思想参见直线的Bresenham画法【算法流程图】【算法代码】void PaintArea::drawCircleBresenham(QPainter &painter,const QPoint ¢er, int r) {int x,y,delta,delta1,delta2,direction;x=0;y=r;delta=2*(1-r);while(y>=0){painter.drawPoint(x,y);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){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;}}}椭圆弧⽣成算法基本同圆弧算法,只是⽅程变得复杂F(x,y)=(bx)^2+(ay)^2-(ab)^2.对称性:4分对称,画第⼀象限分段依据:斜率为⼀点上段圆弧:下段圆弧:【椭圆中点算法流程图】【算法代码】void PaintArea::drawEllipseMiddle(QPainter &painter,int xCenter,int yCenter, int Rx, int Ry) {int Rx2=Rx*Rx;int Ry2=Ry*Ry;int twoRx2=2*Rx2;int twoRy2=2*Ry2;int p,x=0,y=Ry,px=0,py=twoRx2*y;void ellipsePlotPoints(QPainter&,int,int,int,int);ellipsePlotPoints(painter,xCenter,yCenter,x,y);//Region1p=round(Ry-(Rx2*Ry)+(0.25*Rx2));while(px<py){x++;px+=twoRy2;if(p<0)p+=Ry2+px;else{y--;py-=twoRx2;p+=Ry2+px-py;}ellipsePlotPoints(painter,xCenter,yCenter,x,y);}//Region2p=round(Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2);while(y>0){y--;py-=twoRx2;if(p>0)p+=Rx2-py;else{ x++;px+=twoRy2;p+=Rx2-py+px;}ellipsePlotPoints(painter,xCenter,yCenter,x,y);}}void ellipsePlotPoints(QPainter &painter,int xCenter,int yCenter,int x,int y){ painter.drawPoint(xCenter+x,yCenter+y);painter.drawPoint(xCenter-x,yCenter+y);painter.drawPoint(xCenter+x,yCenter-y);painter.drawPoint(xCenter-x,yCenter-y);}软件截图这个绘图软件是⽤QT写的,我会另外写⼀篇介绍编程结构,待续~转载请注明出处:。
Bresenham算法画圆并填充实验报告 09009202 陶园

计算机图形学实验报告实验二Bresenham算法画圆并填充学号:09009202 姓名:陶园成绩:东南大学计算机科学与工程学院二〇一一年十一月一.实验题目Bresenham算法画圆并填充二.算法思想1.首先,真实的线条是连续的,但是计算机中的线条是离散的,是由很多点组成的,那么画线的重点就是如何高效地找到这些离散的点来更好地画出想要的图形。
2.实验要求用Bresenham算法实现画圆。
那么首先先要了解Bresenham算法是一种什么算法。
经过查阅,我找到Bresenham直线算法和画圆算法。
直线是圆的基础。
Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点。
这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。
是计算机图形学中最先发展出来的算法。
Bresenham画圆算法又称中点画圆算法,与Bresenham 直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。
为了简便起见,考虑一个圆心在坐标原点的圆,而且只计算八分圆周上的点,其余圆周上的点利用对称性就可得到。
Bresenham直线算法流程图圆的八对称性所以,只需要知道圆上的一个点的坐标 (x, y) ,利用八对称性,就能得到另外七个对称点的坐标。
和直线算法类似,Bresenham画圆算法也是用一系列离散的点来近似描述一个圆。
Bresenham画圆算法的流程图三.源代码#include "stdlib.h"#include "math.h"#include <gl/glut.h>//按坐标画点void draw(GLint xCoord, GLint yCoord){glBegin(GL_POINTS);//以点的形式glVertex2i(xCoord, yCoord);//在(xCoord, yCoord)坐标下画点glEnd();glFlush();//强制刷新}void Circle(GLint x,GLint y){int a=abs(x);//将x的绝对值赋给aint b=abs(y);//将y的绝对值赋给bint c=a*-1;//使c=a的相反数int d=b*-1;//使d=b的相反数draw(x, y); draw(y, x);draw(-x, y); draw(y, -x);draw(x, -y); draw(-y, x);draw (-x, -y); draw(-y, -x);//按照圆的对称性以圆心为对称点将四个象限的圆周画出for(int i=c;i<=a;i++){for(int j=d;j<=b;j++){draw(i,j);}}//以a,b,c,d为边界用点填充该圆}//主函数void BresenhamCircle(GLint r){int d, d1, d2, direct;GLint x,y;x=0;y=r;d = 2*(1-r);while(y>=0){Circle(x,y);if(d < 0){d1 = 2* (d+ y) -1;if(d1 <=0)direct = 1;elsedirect = 2;}else{if( d > 0){d2 = 2*(d-x)-1;if(d2 <= 0)direct = 2;elsedirect = 3;}elsedirect = 2;}switch(direct){case 1:x++;d+=2*x + 1;break;case 2:x++; y--;d+=2*(x-y+1) + 1;break;case 3:y--;d+=-2*y + 1;break;}}}void RenderScene(void){BresenhamCircle(50);//主函数调用}//当窗口大小改变时由GLUT函数调用void ChangeSize(GLsizei width, GLsizei Height){GLfloat aspectRatio;if (Height == 0){Height = 1;}glViewport(0, 0, width, Height);//指定视口矩形左下角glMatrixMode(GL_PROJECTION);//指定当前矩阵,对投影矩阵应用随后的矩阵操glLoadIdentity();// 装载单位矩阵aspectRatio = (GLfloat)width / (GLfloat) Height;if (width <= Height){glOrtho(-100.0, 100.0, -100.0 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);}else{glOrtho(-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);}glMatrixMode(GL_MODELVIEW);//指定当前矩阵,对模型视景矩阵堆栈应用随后的矩阵操作glLoadIdentity();// 装载单位矩阵}//主程序入口void main(void){glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置初始显示模式,指定单缓存窗口,指定RGB 颜色模式的窗口glutCreateWindow("圆");//创建窗口,窗口名称为“圆”glutDisplayFunc(RenderScene);//进行画图glutReshapeFunc(ChangeSize);//重画回调函数glutMainLoop();//进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环}四.结果截屏五.出现问题及解决方案1.对于如何填充整个圆一开始没有好的方法,后来决定每画一个点,就将该横坐标的所有纵坐标点画出,从下到上,整个填充圆从中间到两边形成。
计算机图形学-三种直线生成算法及圆的生成算法

计算机科学与技术学院2013-2014学年第一学期《计算机图形学》实验报告班级:110341C学号:110341328姓名:田野教师:惠康华成绩:实验(一):平面图形直线和圆的生成一、实验目的与要求1.在掌握直线和圆的理论基础上,分析和掌握DDA生成直线算法、中点生成直线算法、Bresenham生成直线算法、中点画圆算法、Bresenham圆生成算法。
2.熟悉VC6.0MFC环境,利用C语言编程实现直线和圆的生成。
3.比较直线生成三种算法的异同,明确其优点和不足。
同时了解圆的生成算法适用范围。
二、实验内容1.掌握VC6.0环境中类向导和消息映射函数的概念,并且为本次实验做好编程准备工作。
2. 用C语言进行编程实现上述算法,并且调试顺利通过。
3. 在MFC图形界面中显示不同算法下的图形,并且注意对临界值、特殊值的检验。
完成后保存相关图形。
三、算法分析➢DDA直线生成算法描述:1)给定一直线起始点(x0,y0)和终点(x1,y1)。
分别计算dx=x1-x0,dy=y1-y0。
2)计算直线的斜率k=dy/dx。
当|k|<1时转向3);当|k|<=1时,转向4);3)当x每次增加1时,y增加k。
即(xi,yi)→(xi+1,yi+k)。
直到xi增加到x1。
并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对y坐标要进行int(y+0.5)取整运算。
结束。
4)对y每次增加1时,x增加1/k,即(xi,yi)→(xi+1/k,yi+1)。
直到yi增加到y1. 并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对x坐标要进行int(x+0.5)取整运算。
结束。
➢中点生成算法描述:算法基本思想:取当前点(xp,yp),那么直线下一点的可能取值只能近的正右方点P1(xp+1,yp)或者P2(xp+1,yp+1)。
为了确定好下一点,引入了这两点中的中点M(xp+1,yp+0.5)。
这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。
Bresenham 画圆算法_计算机图形学实用教程(第3版)_[共3页]
![Bresenham 画圆算法_计算机图形学实用教程(第3版)_[共3页]](https://img.taocdn.com/s3/m/5c9f4c2e0242a8956aece48f.png)
55 01e r =− (3-39) 这样,由于判别式的初值为整数,增量也为整数,因此判别式始终为整数,即中点画圆算法可用整数加减运算来计算圆周上所有像素的位置。
中点画圆算法的描述如下。
(1)输入圆的半径r 和圆心坐标(x c , y c ),先计算以原点为圆心、r 为半径的圆周上的点,令初始点为00(,)(0,)x y r =。
(2)求初始判别式d ,1d r =−。
(3)在每一个x n 的位置,从n = 0开始,进行下列检测:如果d <0,则圆心在原点的圆的下一个点为(x n +1, y n ),且23n d d x =++;否则,圆的下一个点为(x n +1, y n −1),且2()5nn d dx y =+−+。
(4)确定(x n+1, y n +1)在其余7个八分圆中的对称点位置。
(5)将计算出的每个像素位置(x , y )平移到圆心位于(x c , y c )的圆的轨迹上,即分别沿水平和垂直方向平移x c 和y c ,平移后的坐标值为(x', y' ),c x x x ′=+,c y y y ′=+。
(6)重复第(3)至(5)步,直到x ≥y 时为止。
下面以半径r = 10、圆心在原点的圆为例来说明按上述算法计算第一八分圆上的像素位置的过程。
首先求出初始点(x 0, y 0) = (0, 10),判别式d 0 = 1−r =1−10 = −9,其后续的判别式计算结果和生成的像素位置如表3-1所示。
经过计算最后生成的从(x 0, y 0)到(x 7, y 7)第一八分圆上的8个像素位置如图3-8所示。
表3-1以原点为圆心r =10的第一八分圆的判别式的值和像素位置 n d 2x n + 32x n − 2y n + 5 (x n , y n ) 0 −9 3- (0, 10) 1 −6 5- (1, 10) 2 −1 7- (2, 10) 3 6 -−9 (3, 10) 4 −3 11- (4, 9) 5 8 -−3 (5, 9) 6 5 -1 (6, 8) 7 6 - - (7, 7)3.2.4 Bresenham 画圆算法与中点画圆算法一样,Bresenham 画圆算法也是先考虑圆心在原点、半径为r 的第一四分圆的生成,即取(0, r )为起点,按顺时针方向生成第一四分圆,然后根据圆的对称特性通过对称变换生成整圆。
图形学实验报告-Bresenham算法画圆

计算机图形学实验报告姓名:张晓波学号:090081322010 年10月实验1 实用OpenGL 绘制二维图形实验目的1.进一步了解OpenGL程序的框架。
2.掌握利用OpenGL绘制简单视图的方法。
3.利用OpenGL中的Bresenham算法直接利用像素点绘制图形。
实验要求1.明确实验目的,按实验内容及基本步骤完成实验。
2.在实验过程中,结合思考与探究中的问题,通过实验进行理解。
3.理解并掌握本实验的内容。
实验内容及基本步骤1.绘制圆形分析:利用Bresenham算法,可以在自定了第一个点之后算出下一个点的位置,由于要保证斜率小于1,而且只在一个象限内绘制,所以找出的只是1/8圆弧,因此在找点的时候,利用对称性,同时找到8个点,进行绘制。
void Circle(int r){int x=0,y=r; //初始点int d=0; //声明决策变量d=3-2*r;while(x<=y){CircleVertex(x,y);//画圆上点FillCircle(x,y); //选取对应点,用矩形填充if(d<0)d=d+4*x+6;else{d=d+4*(x-y)+10;y --;}x++;}}void CircleVertex(int x, int y){glBegin(GL_POINTS);glVertex2f( x, y);//右上角glVertex2f(- x, y);//左上角glVertex2f( x,- y);//右下角glVertex2f(- x,- y);//左下角//上下侧四个点glVertex2f( y, x);//右上角glVertex2f(- y, x);//左上角glVertex2f( y,- x);//右下角glVertex2f(- y,- x);//左下角//左右侧四个点glEnd();}试验结果如下:2.填充圆形分析:在一次寻找确定出8个点之后,可以将其上下两端的点作为一组,左右两端的点作为一组分别绘制实心四边形。
计算机图形学课件第2讲:直线及圆生成算法

di 0 di 0
xi1 xi 1
22
中点画线算法
例:利用中点画线算法绘制一条直线:两端点分别为P0(0,0) 、P1(5,2)。
解:首先计算斜率k=0.4 ,因为斜率k小于1,故适用推导。
a=y0-y1=-2 , b=x1-x0=5 , d0=b=5 d1=2a=-4 , d2=2(a+b)=6
M
15
中点画线算法
令M为P1和P2的中点,易知M的坐标为 (xp+1,yp+0.5)。设Q是理想直线与垂直线x=xp+1的 交点。显然,若M在Q的下方,则P2离直线近,应 取为下一个像素;否则应P1 。
16
中点画线算法
问题:判断距离理想直线最近的下一个像素点
已知:线段两端点(x0,y0),(x1,y1) 直线方程:F(x,y)=ax+by+c=0
直线及圆生成算法
光栅图形学
Display processor
Frame buffer
Video Controller
Monitor
2
光栅图形学
0 1 2 ... 0 1 2 . . .
y
x 3
光栅图形学
4
二维图形的显示
是指完成图元的参数表示形式到点阵表示形式的 转换。通常也称扫描转换图元(Scan Conversion)
setPixel( x, y ); error = error + dy; if (error >= 0) { ++y; error = error - dx ; } }
33
斜率的问题
当斜率k>1, DDA, Bresenham算法:
34
计算机图形学圆弧生成算法具体程序实现

e=1-r;
this->CirclePoints(x,y,color,pDC);
while(x<=y)
{
if(e<0)
{
e+=2*x+3;
}
else
{
e+=2*(x-y)+5;
y--;
}
x++;
this->CirclePoints(x,y,color,pDC);
}
}
实验结果:
六:椭圆的绘制
(1):基本原理
while(dx<dy)
{
x++;
dx+=twobb;
if(d<0)
{
d+=bb+dx;
}
else
{
dy-=twoaa;
d+=bb+dx-dy;
y--;
}
pDC->SetPixel(xc+x,yc+y,color);
pDC->SetPixel(xc+x,yc-y,color);
pDC->SetPixel(xc-x,yc+y,color);
d =F(1,b-0.5)= b + a (b-0.5) -a b
= b + a (-b+0.25)
其中,每一步的迭代过程中需要随时的计算和比较从上部分转入下部分的条件是否成立,从而将逼近方向由x改为y。
2.代码实现及结果:
#include "math.h"
class CCircle
{
protected:
}
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《计算机图形学实验报告》样例
实验名称:圆周画法的实现
1.实验内容
1.画出圆心坐标为(75,90)和半径为50的红色圆周
2.画出圆心坐标为(‐40,‐80)和半径为60的蓝色圆周
2.程序的基本思路和功能
先用MFC构建界面外观,然后在相应位置分别用Bresenham和DDA编辑画圆的程序然后编译运行。
3.关键代码及说明
void Circle::circleMinPoint(CDC* pDC)
{
xCenter = (float)(400 + x);
yCenter = (float)(300 - y);
//绘制圆心
drawCenter(pDC);
//r = 50;
//设置颜色
color = RGB(red,green,blue);
float m_x = 0;
float m_y = r;
float d = 1.25 - r;
circlePoint(m_x,m_y,pDC);
while(m_x <= m_y){
if(d<=0){
d = d + 2 * m_x + 3;
}else{
d = d + 2 * ( m_x - m_y ) + 5;
m_y = m_y - 1;
}
m_x = m_x + 1;
circlePoint(m_x,m_y,pDC);
}
}
void Circle::circleBresenham(CDC* pDC) {
//确认圆心坐标
xCenter = (float)(400 + x);
yCenter = (float)(300 - y);
//绘制圆心
drawCenter(pDC);
//r = 50;
//设置颜色
color = RGB(red,green,blue);
float m_x = 0;
float m_y = r;
float p = 3 - 2 * r;
circlePoint(m_x,m_y,pDC);
do{
if( p>=0 ){
p = p + 4 * ( m_x - m_y ) + 10;
m_y = m_y - 1;
}else{
p = p + 4 * m_x + 6;
}
m_x = m_x + 1;
circlePoint(m_x,m_y,pDC);
}while(m_x <= m_y);
}
void Circle::circlePoint(float m_x, float m_y, CDC* pDC) {
//设置颜色
//COLORREF color = RGB(red,green,blue);
float c_x;
float c_y;
//1:一上
c_x = xCenter + m_x;
c_y = yCenter - m_y;
pDC->SetPixel((int)c_x,(int)c_y,color);
//2:一下
c_x = xCenter + m_y;
c_y = yCenter - m_x;
pDC->SetPixel((int)c_x,(int)c_y,color); //3:三下
c_x = xCenter - m_x;
c_y = yCenter + m_y;
pDC->SetPixel((int)c_x,(int)c_y,color); //4:三上
c_x = xCenter - m_y;
c_y = yCenter + m_x;
pDC->SetPixel((int)c_x,(int)c_y,color); //5:四下
c_x = xCenter + m_x;
c_y = yCenter + m_y;
pDC->SetPixel((int)c_x,(int)c_y,color); //6:四上
c_x = xCenter + m_y;
c_y = yCenter + m_x;
pDC->SetPixel((int)c_x,(int)c_y,color); //7:二上
c_x = xCenter - m_x;
c_y = yCenter - m_y;
pDC->SetPixel((int)c_x,(int)c_y,color); //8:二下
c_x = xCenter - m_y;
c_y = yCenter - m_x;
pDC->SetPixel((int)c_x,(int)c_y,color);
}
void Circle::drawCenter(CDC* pDC)
{
pDC->SetPixel((int)xCenter,(int)yCenter,color);
pDC->SetPixel((int)xCenter+1,(int)yCenter,color);
pDC->SetPixel((int)xCenter,(int)yCenter+1,color);
pDC->SetPixel((int)xCenter+1,(int)yCenter+1,color);
pDC->SetPixel((int)xCenter-1,(int)yCenter,color);
pDC->SetPixel((int)xCenter,(int)yCenter-1,color);
pDC->SetPixel((int)xCenter-1,(int)yCenter-1,color);
}
4.程序运行结果及分析
5.其它。