计算机图形学画圆算法源程序
画圆环算法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语言实现中点画圆算法的程序代码。
计算机图形学--圆的生成算法的实现
三、实验结果分析 1、显示圆上的 8 个对称点的算法如下:
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); }
2 ) 7+ 3 2 7( 2 1)
5=2R-3R/
2
5(2R-3R/ 2 )/(R/ 2 ) 4.8
通过实际的程序运行进行比较,结论是中点画圆法速度比较快, 就算法本身而言,该算法仍可以在某些方面进行改进,如其中的浮点 运算改为整数运算等,执行速度将更快。生成直线和圆这类基础算法 在编程时要被无数次的调用,可能每生成一帧画面就要被调用成百上 千次,因此其执行速度是至关重要的。而这类基础算法的长度都很短, 即使多用一些分支,多用一些变量和语句,一般来说只不过是增加几 十个语句,这样的空间增加与算法极其重要的速度来比较是相对次要 的因素。因此在开发图形学的基础算法时,如果有可能提高算法的速 度,应不惜多占用一些存储空间。
2
{ int i,j; for(i=-n/2;i<=n/2;i++) for(j=-n/2;j<=n/2;j++) putpixel(x+j,y+i,color);
} void putpixelt(int x,int y,int color,int i) {int a[8]={1,1,1,1,0,0,0,0}; if(a[i%8])putpixel(x,y,color); } void EllipsePoints(int x,int y,int color) { putpixel(xo+x,yo+y,color);
【计算机图形学】基本图形元素:圆的生成算法
【计算机图形学】基本图形元素:圆的⽣成算法圆的特征圆被定义为到给定中⼼位置(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.对于如何填充整个圆一开始没有好的方法,后来决定每画一个点,就将该横坐标的所有纵坐标点画出,从下到上,整个填充圆从中间到两边形成。
计算机图形学圆的生成
1、当F(M)<0时, M在圆内(圆弧A),说明点E距离圆更近,应取E点; 2、当F(M)>0时, M在圆外(圆弧B),表明SE点离圆更近,应取SE点; 3、当F(M)=0时, 在E点与SE点之中任取一个即可,我们约定取SE点。
2.2.3 中点画圆算法思想
我们用中点M的圆函数作为决策变量di,同时用增量法来迭 代计算下一个中点M的决策变量di+1。
2.2.5 中点画圆程序
F(x,y) <0 点(x,y)位于数学圆内 =0 点(x,y)位于数学圆上 >0 点(x,y)位于数学圆外
, 假定当前取点为Pi(xi,yi),如果顺 时针生成圆,那么下一点只能取正 右方的点E(xi+1,yi)或右下方的点 SE(xi+1,yi-1)两者之一。
(2-8)
生成圆的初始条件和圆的生成方向
2.2.4 中点画圆算法实现
1、输入:圆半径r、圆心(x0,y0); 2、确定初值:x=0,y=r、d=5/4-r; 3、While(x<=y) { circlePoints (x,y,color); if(d≥0) { y--; d=d+2(x-y)+5; } else d=d+2x+3; x++; }
2.2 圆的生成
这里仅讨论圆心位于坐标原点的圆的扫描转 换算法,对于圆心不在原点的圆,可先用平 移变换,将它的圆心平移到原点,然后进行 扫描转换,最后再平移到原来的位置。
2.2.1 圆的八分对称性
八分对称性: 圆心位于原点的圆有四条对称轴x=0、y=0、x=y和x=-y, 若 已知圆弧上一点P(x,y),就可得到其关于四条对称轴的七个对称点。因 此只要能画出八分之一的圆弧,就可以用对称性的原理得到整个圆弧。
12864液晶屏上画圆算法函数(源代码)
二、中心点画圆(算法 2)
/**************************************************/ //函数名称:draw_circle(int x0,int y0,int r,int colour) //函数功能:在 12864 液晶屏上画圆(已知圆心和半径) //返回值:无 //(x0,y0)为圆心,r 为半径 /**************************************************/ void draw_circle(int x0,int y0,int r,int colour) { int x,y; float d; x=0; y=r; d=1.25-r; while(x<=y) { draw_point(x0+x,y0+y,colour); draw_point(x0+x,y0-y,colour); draw_point(x0-x,y0+y,colour); draw_point(x0-x,y0-y,colour); draw_point(x0+y,y0+x,colour); draw_point(x0+y,y0-x,colour); draw_point(x0-y,y0+x,colour); draw_point(x0-y,y0-x,colour); if(d<0) d+=x*2.0+3; else { d+=2.0*(x-y)+5; y--; } x++; } }
一、中心点画圆(算法 1)
/**************************************************/ //函数名称:draw_circle(uchar x0,uchar y0,uchar r) //函数功能:在 12864 液晶屏上画圆(已知圆心和半径) //返回值:无(不带 colour 变量) //(x0,y0)为圆心,r 为半径 /**************************************************/ void draw_circle(uchar x0,uchar y0,uchar r) { uint xx,rr,x,y,rs,col,row;//col:列 row:行 y=r; rr=r*r+1; //补偿 1 修正方形 rs=(y+(y>>1))>>1; //(*0.75)分开 1/8 圆弧来画 for (x=0;x<=rs;x++) { xx=x*x; while ((y*y)>(rr-xx)) y--; col=x0+x; //第一象限 row=y0-y; draw_point(col,row,1); col=x0-x; //第二象限 draw_point(col,row,1); row=y0+y; //第三象限 draw_point(col,row,1); col=x0+x; //第四象限 draw_point(col,row,1); /***************45 度镜象画另一半***************/ col=x0+y; row=y0-x; draw_point(col,row,1); col=x0-y; draw_point(col,row,1); row=y0+x; draw_point(col,row,1); col=x0+y; draw_point(col,row,1); } } //第一象限
c++ 圆形算法
在C++中,绘制圆形需要使用一些基本的几何和数学公式。
如果你想在一个二维平面上绘制一个圆形,你可以使用极坐标系中的公式:r = ρ * cos(θ)r = ρ * sin(θ)其中,ρ是半径,θ是角度(通常从0到2π)。
如果你想要在一个像素矩阵(例如二维数组)上绘制一个圆形,你可能需要写一个循环,检查每个像素是否在圆内。
以下是一个简单的C++代码示例,它在N*N的二维数组上绘制一个圆心在(N/2, N/2)的圆形。
该圆形的半径是N/2-1。
```cpp#include <iostream>#include <vector>void drawCircle(std::vector<std::vector<int>>& matrix, int n) {for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {double distance = std::sqrt((i - n / 2) * (i - n / 2) + (j - n / 2) * (j - n / 2));if (distance <= n / 2 - 1) {matrix[i][j] = 1; // Set the pixel to be in the circle} else {matrix[i][j] = 0; // Set the pixel to be outside the circle}}}}int main() {int n = 5; // Define the size of the circlestd::vector<std::vector<int>> matrix(n, std::vector<int>(n, 0)); // Initialize a n*n matrix with zerosdrawCircle(matrix, n); // Draw the circle// Now you can print the matrix or do something elsewith it.return 0;}```这个代码会创建一个N*N的二维数组,并使用上述算法将数组中的每个元素设置为1(如果该点在圆内)或0(如果该点在圆外)。
计算机图形学圆弧生成算法具体程序实现
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.VC++图形函数的使用方法;2.圆和椭圆弧的生成原理;3.理解圆生成的基本原理,掌握几种常见的圆生成算法。
二、实验内容:1、以函数形式编写圆的生成算法,然后在VCAD绘图小系统中的绘图----圆子菜单下找到合适的程序修改点,通过调试来验证你编写的画圆算法的正确性。
2、以函数形式编写角度DDA椭圆弧生成算法,然后在VCAD 绘图小系统中的绘图----圆弧子菜单下找到合适的程序修改点,将本实验要求你编写的画圆弧算法插入工程文件中,通过调试来验证你编写的画圆弧算法的正确性。
3、利用中点画图算法,在屏幕上生成任意一段1/8弧。
利用图的对称性,将(1)题生成的圆弧扩展为一个整圆。
三、实验结果分析:1、圆被定义为到给定中心位置(x,y)距离为r的点集2、比较三种算法的结果:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法1.程序代码:void CMyView::DrawCir(int Start, int R, int a, int b){CDC* pDc=GetDC();int x,y;int e=Start-R;x=Start;y=R;pDc->SetPixel(y+a,x+b,RGB(0,0,255));pDc->SetPixel(-y+a,x+b,RGB(0,0,255));pDc->SetPixel(y+a,-x+b,RGB(0,0,255));pDc->SetPixel(-y+a,-x+b,RGB(0,0,255)); pDc->SetPixel(x+a,y+b,RGB(0,0,255));pDc->SetPixel(-x+a,y+b,RGB(0,0,255));pDc->SetPixel(x+a,-y+b,RGB(0,0,255));pDc->SetPixel(-x+a,-y+b,RGB(0,0,255)); if(e<0){e=e+2*x+3;x++;}pDc->SetPixel(x,y,RGB(0,0,255));while(x<y){if(e<0){e=e+2*x+3;x++;}else{e=e+2*(x-y)+5;x++;y--;}pDc->SetPixel(y+a,x+b,RGB(0,0,255)); pDc->SetPixel(-y+a,x+b,RGB(0,0,255)); pDc->SetPixel(y+a,-x+b,RGB(0,0,255)); pDc->SetPixel(-y+a,-x+b,RGB(0,0,255)); pDc->SetPixel(x+a,y+b,RGB(0,0,255)); pDc->SetPixel(-x+a,y+b,RGB(0,0,255)); pDc->SetPixel(x+a,-y+b,RGB(0,0,255)); pDc->SetPixel(-x+a,-y+b,RGB(0,0,255));}}void CMyView::OnDrawCir(){CMyView::DrawCir(0,50,200,300);}2.程序代码:#include<graphics.h>void circlepoints(int x,int y,int color){int m,n,xasp,yasp;float aspectratio;m=200;n=200;getaspectratio(&xasp,&yasp);aspectratio = xasp/yasp;putpixel(x+m,y*aspectratio+n,color);putpixel(y+m,x*aspectratio+n,color);putpixel(-y+m,x*aspectratio+n,color);putpixel(-x+m,y*aspectratio+n,color);putpixel(y+m,-x*aspectratio+n,color);putpixel(x+m,-x*aspectratio+n,color);putpixel(-x+m,-y*aspectratio+n,color);putpixel(-y+m,-x*aspectratio+n,color);}void midpointcircle(int r,int c){int x,y;float d;x=0; y=r; d=5.0/4-r;circlepoints(x,y,c);while(y>x){if(d<=0)d+=2.0*x+3;else{d+=2.0*(x-y)+5;y--;}x++;circlepoints(x,y,c);}}main(){int a,b;int graphdriver = DETECT;int graphmode = 0;initgraph(&graphdriver,&graphmode,””);cleardevice( );a= 200; b= 2;midpointcircle(a,b);getch( );closegraph( );}.1.运行结果:2.运行结果:。
opengl鼠标绘制直线及圆图元算法源代码
#include <assert.h>#include <cmath>#include <iostream>#include <vector>#include <glut.h>using namespace std;typedef vector<int> list;vector<list> ls, cs;int old_x, old_y, new_x, new_y, cx, cy, cr; int mouse_type;/* breseman画线算法*/void line(int x1, int y1, int x2, int y2) { glBegin(GL_POINTS);if (x1==x2 && y1==y2) {glVertex2i(x1, y1);return;}if (x1>x2) {swap(x1, x2);swap(y1, y2);}glVertex2d(x1, y1);int dy=abs(y2-y1);int dx=abs(x2-x1);if (dx>=dy) {int incy=(dy!=0?dy/(y2-y1):0);int p=2*dy-dx;int dy2=2*dy;int dd2=2*(dy-dx);int x, y=y1;for (x=x1+1; x<=x2; ++x) {if (p<0) {glVertex2i(x, y);p+=dy2;}else {y+=incy;glVertex2i(x, y);p+=dd2;}}}else {if (y1>y2) {swap(x1, x2);swap(y1, y2);}int incx=(dx!=0?dx/(x2-x1):0);int p=2*dx-dy;int dx2=2*dx;int dd2=2*(dx-dy);int x=x1, y;for (y=y1+1; y<=y2; ++y) {if (p<0) {glVertex2i(x, y);p+=dx2;}else {x+=incx;glVertex2i(x, y);p+=dd2;}}}glEnd();}/* 中点圆算法*/void circle(int cx, int cy, int r) { int x=0, y=r;float p=1.25-r;while (x<=y) {glBegin(GL_POINTS);glVertex2i(cx+x, cy+y);glVertex2i(cx-x, cy+y);glVertex2i(cx-x, cy-y);glVertex2i(cx+x, cy-y);glVertex2i(cx+y, cy+x);glVertex2i(cx-y, cy+x);glVertex2i(cx-y, cy-x);glVertex2i(cx+y, cy-x);glEnd();if (p<0) {++x;p+=2*x+1;}else {p+=2*x-2*y+5;++x;--y;}}}void draw(){int i;for (i=0; i<ls.size(); ++i)line(ls[i][0], ls[i][1], ls[i][2], ls[i][3]);for (i=0; i<cs.size(); ++i)circle(cs[i][0], cs[i][1], cs[i][2]);if(mouse_type == 1)line(old_x, old_y, new_x, new_y);if(mouse_type == 3)circle(cx, cy, cr); //圆上的点和半径}void display() {glClear(GL_COLOR_BUFFER_BIT);glColor3i(0, 0, 0);draw();glutSwapBuffers();}void keyboard( unsigned char key, int x, int y) {switch (key) {case 27:exit (0);break;case 'a':case 'A':break;default:if (key<='z' && key>='a' || key<='Z' && key>='A' || key<='9' && key>='0'){ cout<<char(key);}else{cout<<"\n字符码为"<<static_cast<int>(key);display();}}}void mouseclick( int button, int state, int x, int y ){cout<<"("<<x<<","<<y<<")";switch ( button ) {case GLUT_LEFT_BUTTON:if ( state == GLUT_DOWN ) {cout<<"左键被按下";old_x = x;old_y = 600-y;mouse_type = 1;}else if ( state == GLUT_UP ) {cout<<"左键被松开";list l;l.push_back(old_x);l.push_back(old_y);l.push_back(x);l.push_back(600-y);ls.push_back(l);mouse_type = 0;glutPostRedisplay();for(int i=0; i<ls.size(); ++i)cout<<endl<<"line_"<<i<<": "<<ls[i][0]<<","<<ls[i][1]<<" "<<ls[i][2]<<","<<ls[i][3];}break;case GLUT_MIDDLE_BUTTON:break;case GLUT_RIGHT_BUTTON:if ( state == GLUT_DOWN ) {cout<<"右键被按下";cx = x;cy = 600-y;mouse_type = 3;}else if ( state == GLUT_UP ) {cout<<"右键被松开";list l;l.push_back(cx);l.push_back(cy);cr=int(sqrt(double(x-cx)*(x-cx)+(600-y-cy)*(600-y-cy))+0.5);l.push_back(cr);cs.push_back(l);mouse_type = 2;glutPostRedisplay();for(int i=0; i<cs.size(); ++i)cout<<endl<<"circle_"<<i<<": "<<cs[i][0]<<","<<cs[i][1]<<" "<<cs[i][2];}break;}}void screenmotion(int x, int y){if(mouse_type == 1){new_x = x;new_y = 600-y;cout<<endl<<"new-line:"<<old_x<<","<<old_y<<" "<<new_x<<","<<new_y<<endl; }else if(mouse_type == 3){cr=int(sqrt(double(x-cx)*(x-cx)+(600-y-cy)*(600-y-cy))+0.5);cout<<endl<<"new-circle: "<<cx<<","<<cy<<" "<<cr<<endl;}glutPostRedisplay();}void init() {glClearColor(0.2, 0.5, 0.8, 0.0); //背景颜色glMatrixMode(GL_PROJECTION);gluOrtho2D(-1.0, 600, 0.0, 601);}int main(int argc, char** argv) {glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);glutInitWindowPosition(100, 50); //图框在屏幕的位置glutInitWindowSize(600, 600); //边框大小glutCreateWindow("图元算法"); //图框边显示的字init();glutDisplayFunc(display);glutMotionFunc(screenmotion);glutKeyboardFunc( keyboard );glutMouseFunc( mouseclick );glutMainLoop();return 0;}。
计算机图形学画圆方法
浙江大学城市学院实验报告课程名称计算机图形学实验项目名称画圆方法实验成绩指导老师(签名)日期一. 实验目的和要求通过实验加深对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;⑧保存,完成。
计算机图形学圆的生成算法的实现
申明:
所有资料为本人收集整理,仅限个人学习使用,勿做商业用途。
OnMidpointellispe
表1 生成圆和椭圆的菜单项资源及消息处理函数
<3)添加程序代码
在CMyView.cpp文件中相应的位置添加各算法的程序代码,在Visual C++的MFC中绘制图形,一般可以调用一个“CDC”类,从CDC开始,添加代码。5PCzVD7HxA
中点算法画圆。利用中点画圆算法画出圆心在 、半径为R的圆,其VC程序设计代码如下:
pDC->SetPixel(y+x0,x+y0,color>。
pDC->SetPixel(-y+x0,x+y0,color>。
pDC->SetPixel(-y+x0,-x+y0,color>。
pDC->SetPixel(y+x0,-x+y0,color>。
}
ReleaseDC(pDC>。
}
Bresenham算法画圆。利用Bresenham画圆算法画出圆心在 、半径为R的圆,其VC程序设计代码如下:jLBHrnAILg
pDC->SetPixel(x+x0,-y+y0,color>。
}
ReleaseDC(pDC>。
}
计算机图形学实验 光栅 中点画圆
}
MidPointCircle部分
void CCGView::MidPointCircle(int r,COLORREF color)
{
int x,y;
int e;
x=0;y=r;e=1-r;
CirclePoints(x,y,color);
3、思考能否像实验五那样,做出一个菜单来实现画圆?
三、实验设备:
微机,Visual C++6.0
四、
1、打开VC,打开原来建立的工程CG。文件名应该为cg.dsw。
2、在CGView.cpp文件中(类CCGView中),添加函数voidMidPointCircle(int r, COLORREF color)和voidCirclePoints(int x, int y, COLORREF color)。方法如下:在VC界面的ClassView中,右键单击CCGView类,出现图1所示的界面,点击“Add Member Function…”菜单,出现图2的对话框,在其中分别完成对函数MidPointCircle和CirclePoints的定义和声明。
图1
图2
3、在函数体voidMidPointCircle(int r, COLORREF color)和voidCirclePoints(int x, int y, COLORREF color)中,实现中点画圆的算法。具体代码参考教材P34和P36。需要注意的是,CirclePoints函数中调用Setpixel函数之前需要得到设备上下文,即在函数体前部加入如下代码:
这样圆就可以画出。
2、如果不打开cg.dsw文件而是打开ccgview.cpp文件进行编程,会造成什么后果?
计算机图形学实验报告模板圆的扫描转换
北京联合大学应用文理学院实验报告课程名称计算机图形学实验(实训)名称圆的扫描转换班级信息与计算科学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 画圆法进行圆的扫描转换的生成原理。
计算机图形学实验三 圆的生成算法的实现
实验三圆的生成算法的实现班级 08信计学号 60姓名段丹丹分数一、实验目的与要求1. 掌握Bresenham画圆算法的基本思想。
2. 编写Bresenham算法画圆的基本函数并尽量完善。
3、熟悉圆的生成算法,掌握圆的绘制,利用TurboC来实现圆的生成算法。
3、熟悉生成圆的中点算法和正负法。
4、理解圆生成的基本原理。
二、实验步骤与内容:在光栅显示器上显示图形时,直线段或图形边界或多或少会呈锯齿状,原因是图形信号时连续,而在光栅显示系统中,用来表示图形的却是一个个离散的像素,这种用离散量表示连续两引起的失真现象称之为走样,用于减少或消除这种效果的技术称为饭走样技术。
采用反走样可适当减轻锯齿效果,但需要以额外的软件或者硬件来实现。
通常的,我们利用画图算法,在屏幕上生成任意一段八分之一圆弧,再利用图的对称性,将那段圆弧扩展为一个整1.圆的特征圆被定义为到给定中心位置(x,y)距离为r的点集。
圆心位于远点的圆有4条对称轴:分别为:x=0,y=0,x=y,x=-y.若已知圆弧上一点(x,y),可以得到其关于4条对称轴的其他7个点,这个性质叫做8对称型。
因此只要扫描转换八分之一圆弧,就可以求出整个圆弧的像素集。
2.生成圆的中点算法在第i点已经选择A时,第i+1点只能选择B或C,D为圆弧与直线BC的交点,M为线段BC的中点,M在圆内选B,M在圆外选C设圆的方程为F(x,y)=0,M在圆内时F(M)<0, M在圆外时F(M)>0 ,M在圆上时F(M)=0主要算法:设d i=F(M),则d i>0,选C;d i< = 0,选Bd i=F(x i +1,y i,r - 1/2)= (x i +1)2+(y i,r - 1/2)2- R2d i+1=F(x i+1 +1,y i+1,r - 1/2)= (x i+1 +1)2+(y i+1,r - 1/2)2- R2初始条件:(x0,y0,r)=(0,R)d0=F(x0 +1,y0,r – 1/2)=5/4-R结束条件:x i>=y i圆心为任意点(x c,y c)。
c语言circle画圆函数
C语言circle画圆函数介绍在C语言中,我们可以使用数学库函数和循环结构来实现画圆的功能。
本文将详细介绍如何使用C语言编写一个画圆的函数,并提供代码示例和详细解释。
基本原理画圆的基本原理是通过计算圆上每个点的坐标,并将其绘制在屏幕上。
在C语言中,我们可以使用数学库函数来计算圆上的点的坐标,然后使用循环结构将这些点绘制出来。
代码示例下面是一个简单的C语言程序,用于实现画圆的函数:#include <stdio.h>#include <math.h>void drawCircle(int centerX, int centerY, int radius) {int x, y;for (x = centerX - radius; x <= centerX + radius; x++) {y = centerY + sqrt(radius * radius - (x - centerX) * (x - centerX));printf("(%d, %d)\n", x, y);}}函数解析该程序中的drawCircle函数接受三个参数:圆心的x坐标、圆心的y坐标和半径。
函数内部使用一个循环结构来计算圆上的点的坐标,并将其打印出来。
循环结构的起始点为圆心的x坐标减去半径,终止点为圆心的x坐标加上半径。
在每次循环中,我们使用数学库函数sqrt来计算圆上相应x坐标的y坐标。
这里使用了圆的方程y = sqrt(radius * radius - (x - centerX) * (x - centerX))。
下面是一个调用drawCircle函数的示例:int main() {int centerX = 0;int centerY = 0;int radius = 5;drawCircle(centerX, centerY, radius);return 0;}参数说明•centerX:圆心的x坐标。