圆的生成算法
- 格式:doc
- 大小:386.00 KB
- 文档页数:5
给定经纬度半径生成圆的方法【原创版5篇】目录(篇1)1.圆的生成方法的背景和需求2.给定的经纬度和半径3.计算圆心坐标4.计算圆的半径5.应用圆的生成方法正文(篇1)在许多地理信息系统和地图应用中,我们常常需要根据给定的经纬度和半径生成一个圆。
这种方法可以帮助我们表示一个特定的区域,例如一个城市的范围、一个自然保护区的边界等。
首先,我们需要知道给定的经纬度和半径。
经纬度是地球表面上一个点的精确位置,通常用度数来表示。
半径则是圆的直径,它决定了圆的大小。
接下来,我们需要计算圆心的坐标。
圆心的坐标是圆的中心点,通常用经纬度表示。
为了计算圆心的坐标,我们可以将给定的经纬度作为基准,然后根据半径的大小计算出圆心的具体位置。
然后,我们需要计算圆的半径。
半径是圆的直径,它决定了圆的大小。
通常,半径是给定的,但是在某些情况下,我们可能需要根据实际情况来计算半径。
最后,我们可以应用圆的生成方法。
根据计算出的圆心坐标和半径,我们可以生成一个完整的圆形。
这个圆形可以帮助我们更好地理解给定区域的大小和形状,也可以用于进一步的分析和应用。
总的来说,根据给定的经纬度和半径生成圆的方法是一种常用的地理信息处理方法。
目录(篇2)1.圆的生成方法概述2.根据经纬度和半径计算圆心坐标3.根据圆心坐标和半径计算圆上任意一点的坐标4.应用实例正文(篇2)一、圆的生成方法概述在地理信息系统(GIS)和地图制图中,经常需要根据给定的经纬度和半径生成一个圆。
为了实现这一目标,我们需要首先了解圆的生成方法。
二、根据经纬度和半径计算圆心坐标给定一个圆的半径和圆上的两点(经纬度),我们可以通过以下步骤计算圆心的坐标:1.计算两点的中点坐标2.计算两点坐标差的平方和3.计算半径的平方4.计算中点坐标与半径平方的乘积5.将结果添加到两点坐标差的平方和中6.开平方得到圆心坐标三、根据圆心坐标和半径计算圆上任意一点的坐标有了圆心的坐标和半径,我们可以通过以下步骤计算圆上任意一点的坐标:1.计算圆心与任意一点的距离2.计算距离与半径的差值3.将差值与圆心坐标相加,得到圆上任意一点的坐标四、应用实例假设我们想要找到一个半径为 100 公里的圆,圆上的点分别位于东经 116.39 度和北纬 39.90 度,以及东经 116.39 度和北纬 39.91 度。
【计算机图形学】基本图形元素:圆的⽣成算法圆的特征圆被定义为到给定中⼼位置(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圆生成算法Bresenham圆生成算法是一种经典的计算机图形学算法,用于在计算机屏幕上绘制圆形。
该算法是由美国计算机科学家Jack E. Bresenham于1965年发明的。
这个算法非常简单,但是它却非常有效,因为它只需要使用整数运算。
Bresenham圆生成算法的基本思想是使用一个叫做“决策参数”的变量来决定下一个像素点的位置。
该变量根据当前像素点到圆心的距离和半径之间的差异进行调整。
如果该差异小于0,则移动到右上方的像素点;否则,移动到右上方和正上方之间的像素点。
具体来说,Bresenham圆生成算法可以通过以下步骤来实现:1. 输入圆心坐标和半径。
2. 初始化x和y坐标为0,并计算出初始决策参数d=3-2r。
3. 在每个步骤中,检查当前像素点是否在圆内。
如果是,则将该像素点绘制出来;否则,不绘制。
4. 计算下一个像素点的位置。
如果d小于0,则移动到右上方;否则,移动到右上方和正上方之间。
5. 更新决策参数d。
Bresenham圆生成算法的优点是它非常快速和有效。
它只需要使用整数运算,因此可以在计算机上非常快速地执行。
此外,该算法还可以轻松地扩展到三维空间中的球体和其他形状。
尽管Bresenham圆生成算法已经有几十年的历史了,但它仍然是计算机图形学中最常用的算法之一。
它被广泛应用于游戏开发、计算机辅助设计、虚拟现实等领域。
此外,该算法还被用于许多其他领域,如数字信号处理和图像处理。
总之,Bresenham圆生成算法是一种简单而有效的计算机图形学算法。
它可以快速地绘制出圆形,并且可以轻松地扩展到其他形状。
尽管这个算法已经有几十年的历史了,但它仍然是计算机图形学中最常用的算法之一,并且在许多其他领域也得到了广泛应用。
§3.2圆的生成——Bresenham算法条件:给定圆心(x c,y c)和半径R约定:只考虑圆心在原点,半径为整数R的圆x2+y2.=R2。
对于圆心不在原点的圆,可先通过平移转换,化为圆心在原点的圆,再进行扫描转换,把所得到的像素集合加上一个位移量,就可以把目标圆光栅化。
在众多圆的生成算法,如逐点比较法、角度DDA法、Bresenham算法中,Bresenham画圆法是一种最简单有效的的方法。
首先注意到只要生成一个八分圆,那么,圆的其它部分就可以通过一系列的对成变换得到。
12345678由算法生成y=x第一八分圆关于y=x对称变换第一四分圆关于x=0对称变换上半圆关于y=0对称变换如果以点x=0,y=R为起点按顺时针方向生成圆,则在第一象限内y是x 的单调递减函数。
要在这三个像素中选择一个使其与理想圆的距离的平方达到最小,即下列数值中的最小者。
R(0,R)(R,0)xy这样,从圆上任一点出发,按顺时针方向生成圆时,为了最佳逼近该圆,对于下一像素的取法只有三种可能的选择,即正右方像素、正下方像素和右下角像素,分别记作:m H、m V、m D。
(x i,y i)(x i,y i-1)(x i+1,y i)(x i+1,y i-1)m Hm Dm Vm H=|(x i+1)2+(y i)2-R2|m V=|(x i)2+(y i+1)2-R2|m D=|(x i+1)2+(y I-1)2-R2|m H(x i,y i)(x i+1,y i)(x i+1,y i+1)(x i+1,y i-1)(x i-1,y i-1)(x i,y i-1)m Vm D12354圆与点(x i,y i)附近光栅格网的相交关系只有五种可能。
从圆心到右下角像素(x i+1,y i-1)的距离平方m D与圆心到圆上点的距离平方R2之差等于:Δi=(x i+1)2+(y i-1)2-R2如果Δi<0,那么右下角像素(x i+1,y i-1)在该圆内(图中①、②),显然这时只能取像素(x i+1,y i),即m H;或像素(x i+1,y i-1),即m D。
圆及圆弧生成算法圆及圆弧生成算法是计算机图形学中常用的算法之一,用于生成圆及圆弧的几何形状。
圆是一个闭合曲线,由一系列连续的点组成,其到中心点的距离都相等。
圆弧是圆的一部分,也是由一系列点组成的曲线。
下面将介绍几种常见的圆及圆弧生成算法。
1.中点圆生成算法:中点圆生成算法是一种常用的生成圆形的算法。
该算法从圆心开始,逐步生成圆上其它点的坐标,直到生成整个圆。
算法的基本思想是在每一步中选择一个点,使得该点的距离到圆的实际弧路径最接近满足圆方程的距离。
具体步骤如下:(1)初始化圆心坐标和半径;(2)设置初始点的坐标为(0,r),即圆上的一个点;(3)设置初始参数值d,初始值为1-r;(4)当x小于等于y时,递归生成圆上的其它点的坐标,具体步骤如下:-如果d<0,则令d=d+2x+3,x=x+1,y=y;-如果d>=0,则令d=d+2x-2y+5,x=x+1,y=y-1;(5)重复步骤(4)直到x大于y结束。
2. Bresenham圆生成算法:Bresenham圆生成算法是基于中点圆生成算法的改进。
该算法的主要思想是通过对称性减少计算量,较中点圆生成算法更快速。
具体步骤如下:(1)初始化圆心坐标和半径;(2)设置初始点的坐标为(0,r),即圆上的一个点;(3)设置初始参数值d,初始值为3-2r;(4)当x小于等于y时,递归生成圆上的其它点的坐标,具体步骤如下:-如果d<0,则令d=d+4x+6,x=x+1,y=y;-如果d>=0,则令d=d+4(x-y)+10,x=x+1,y=y-1;(5)重复步骤(4)直到x大于y结束。
3.中点圆弧生成算法:中点圆弧生成算法是用于生成圆弧的算法。
该算法通过给定圆心、弧的起始点和终止点,计算圆弧上的所有点的坐标。
具体步骤如下:(1)初始化圆心、起始点和终止点坐标;(2)计算圆上点的初始参数值d,初始值根据起始点和终止点的位置关系计算得到;(3)按递增顺序计算圆弧上的点的坐标,具体步骤如下:-如果d<0,则令d=d+4x+6,x=x+1,y=y;-如果d>=0,则令d=d+4(x-y)+10,x=x+1,y=y-1;-输出当前点的坐标;(4)重复步骤(3)直到到达终止点。
实验三圆的生成算法实现班级 08信计学号 80姓名分数一、实验目的和要求:1、理解圆生成的基本原理2、掌握几种常见的圆的生成算法3、实现圆生成的函数,参数,中点画圆的算法….二、实验内容:1.利用生成圆弧的函数算法在屏幕上生成圆弧2.利用生成圆弧参数算法在屏幕上生成圆弧3.利用圆的中点算法在屏幕上生成圆弧4.比较三种算法的优缺点(1)实验代码:#include "Conio.h"#include "graphics.h"#define closegr closegraph#include "math.h"#define pie 3.1415926void initgr(void) /* BGI初始化 */{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */initgraph(&gd, &gm, "");}void CirclePoints(int x,int y,int t,int s,int color){putpixel(t+x,s+y,color);putpixel(s+y,t+x,color);putpixel(s-y,t+x,color);putpixel(t-x,s+y,color);putpixel(s+y,t-x,color);putpixel(t+x,s-y,color);putpixel(t-x,s-y,color);putpixel(s-y,t-x,color);}void EllipsePoints(int x,int y,int t,int s,int color){putpixel(t+x,s+y,color);putpixel(t-x,s+y,color);putpixel(t+x,s-y,color);putpixel(t-x,s-y,color);}/*-----------------------------开平方法生成圆-----------------------------*/ void sqrtCircle(int radius,int color){float x,y;x=0;y=radius;CirclePoints(x,y,100,100,color);while(y>=x){x++;y=sqrt(radius*radius-x*x);CirclePoints((int)(x+0.5),(int)(y+0.5),100,100,color);}outtextxy(50,170,"sqrtCircle");}/*----------------------------参数法生成圆---------------------------------*/ void funCircle(int radius,int color){float x,y,afla;x=radius;y=0;afla=0;CirclePoints(x,y,200,200,color);while (afla<=pie/4){afla+=pie/400;x=radius*cos(afla);y=radius*sin(afla);CirclePoints((int)(x+0.5),(int)(y+0.5),200,200,color);outtextxy(100,250,"funCircle");}}/*----------------------------Bresenham算法生成圆-----------------------------*/BresenhamCircle(int R,int color){int x,y,dD,dHD,dDV,next;x=0;y=R;dD=2*(1-R);while(y>=0){CirclePoints(x,y,300,300,color);if(dD<0){dHD=2*(dD+y)-1;if(dHD<=0) next=0;else next=1;}else if(dD>0){dDV=2*(dD-x)-1;if(dDV<=0) next=1;else next=2;}else next=1;switch(next){case 0:x++;dD+=2*x+1;break;case 1:x++;y--;dD+=2*(x-y+1);break;case 2:y--;dD+=-2*y+1;break;} /*switch*/} /*while*/outtextxy(150,350,"BresenhamCircle");}/*----------------------------中点算法生成圆--------------------------------*/ void MidPointCircle(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(x,y,400,400,color);while(y>x){if(d<=0){d+=deltaE;deltaSE+=8;}else{d+=deltaSE;deltaSE+=16;y--;}deltaE+=8;x++;CirclePoints(x,y,400,400,color);}outtextxy(250,450,"MidPointCircle");}/*---------------------------开平方法生成椭圆---------------------------------*/void sqrtEllipse(int a,int b,int color){float x,y;x=0;y=b;EllipsePoints(x,y,300,100,color);while(x<a){x++;y=sqrt(b*b-(x*x*b*b)/(a*a));EllipsePoints((int)(x+0.5),(int)(y+0.5),300,100,color);}outtextxy(350,100,"sqrtEllipse");}/*---------------------------参数法生成椭圆-----------------------------------*/void funEllipse(int a,int b,int color){float x,y,afla;x=a;y=0;afla=0;EllipsePoints(x,y,400,200,color);while(afla<=pie/2){afla+=pie/400;x=a*cos(afla);y=b*sin(afla);EllipsePoints((int)(x+0.5),(int)(y+0.5),400,200,color);}outtextxy(450,200,"funEllipse");}/*---------------------------中点算法生成椭圆---------------------------------*/void MidPointEllipse(double a,double b,int color){double x,y,d,xP,yP,squarea,squareb;squarea=a*a;squareb=b*b;xP=(int)(0.5+(double)squarea/sqrt((double)(squarea+squareb)));yP=(int)(0.5+(double)squareb/sqrt((double)(squarea+squareb)));x=0;y=b;d=4*(squareb-squarea*b)+squarea;EllipsePoints(x,y,500,300,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,y,500,300,color);}x=a;y=0;d=4*(squarea-a*squareb)+squareb;EllipsePoints(x,y,500,300,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,y,500,300,color);}outtextxy(480,380,"MidPointsEllipse");}int main(void){initgr(); /* BGI初始化 *//*****此部分添加你自己的代码,例如line(25, 25, 220, 220);circle(100, 100, 50);等等*****/sqrtCircle(50,105);funCircle(50,5);BresenhamCircle(50,35);MidPointCircle(50,255);sqrtEllipse(50,80,220);funEllipse(50,80,180);MidPointEllipse(50,80,150);getch(); /* 暂停一下,看看前面绘图代码的运行结果 */ closegr(); /* 恢复TEXT屏幕模式 */return 0;}(2)实验结果:三、实验结果分析. 1、该程序实现了三种算法的圆的绘制2、三种算法很好的实现了圆的生成3、中点算法生成圆优于其他两种算法。
圆周率生成算法一、概述圆周率生成算法是指通过计算得到圆周率的数值。
圆周率是一个重要的数学常数,它代表着圆的周长与直径之比,通常用希腊字母π表示。
圆周率的精确值是一个无限不循环小数,但可以通过不同的算法来逼近它的精确值。
二、历史人类对于圆周率的研究可以追溯到古代文明时期。
早在公元前250年左右,中国数学家刘徽就使用正多边形逼近圆来计算圆周率。
在欧洲,古希腊数学家阿基米德也曾使用类似方法计算过圆周率,并得到了3.14和3.142857这两个近似值。
随着时间的推移,越来越多的数学家和科学家开始探索更加精确地计算出圆周率的方法。
三、常见算法1. 随机法随机法是一种简单而常用的计算圆周率的方法。
该方法基于蒙特卡罗模拟原理,即通过在单位正方形内随机投点,并统计落入单位圆内点的数量来逼近π/4。
具体步骤如下:(1)在一个单位正方形内随机生成N个点;(2)统计落入单位圆内的点的数量M;(3)根据公式π/4=M/N来计算π的近似值。
2. 数学级数法数学级数法是一种基于级数展开的方法,可以通过不断增加级数项来逼近圆周率。
其中最著名的就是莱布尼茨级数和欧拉公式。
具体步骤如下:(1)选择一个适当的级数公式;(2)根据公式依次求出每个级数项的值;(3)将所有级数项相加,并乘以适当系数得到π的近似值。
3. 迭代法迭代法是一种通过不断迭代计算来逼近圆周率的方法。
其中最常用的就是马刁尼迭代法和阿基米德迭代法。
具体步骤如下:(1)选择一个适当的初始值;(2)根据迭代公式依次求出每个新值;(3)将所有新值相加,并乘以适当系数得到π的近似值。
四、应用圆周率生成算法在科学和工程领域中有着广泛应用。
例如,在计算机图形学中,需要使用圆周率来绘制圆形和曲线;在通信领域中,需要使用圆周率来计算频率和相位;在物理学和天文学中,需要使用圆周率来计算物理常数和天体运动等。
五、总结圆周率生成算法是一项重要的数学研究工作,它不仅具有理论意义,还有着广泛的应用价值。
圆的生成算法利用直线坐标法和极坐标法生成圆周颇费时间,而圆的Bresenham算法则简捷很多。
一.圆的Bresenham算法思想:设圆的半径为r,先考虑圆心在(0,0),并从x=0、y=r开始的顺时针方向的1/8圆周的生成过程。
在这种情况下,x每步增加1,从x=0开始,到x=y结束。
即有X i+1=X i+1相应地yi+1则在两种可能中选择:Y i+1=y i或者y i+1=y i-1选择的原则是考虑精确值y是靠近yi还是靠近yi-1,计算公式为Y2=r2-(x i+1)2d1=y i2-y2=y i2-r2+(x i+1)2d2=y2-(y i-1)2=r2-(x i+1)2-(y i-1)2令pi=d1-d2,并代入d1、d2,则有P i=2(x i+1)2+y i2+(y i-1)2-2r2(1)Pi称为误差。
如果Pi<0,则yi+1=yi,否则yi+1=yi-1.pi的递归式为P i+1=p i+4x i+6+2(y i+12-y i2)-2(y i+1-y i) (2)P i的初值由式(1)代入xi=0,yi=r,而得P1=3-2r (3)根据上面的推导,圆周生成算法思想如下:(1)求误差初值,p1=3-2r,i=1,画点(0,r);(2)求下一个光栅位置,其中x i+1=x i+1,如果p i<0,则y i+1=y i,否则y i+1=y i-1;(3)画点(x i+1,y i+1);(4)计算下一个误差,如果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,如果x=y,则结束,否则返回步骤2;虽然(1)式表示p i+1的算法很复杂,但因为y i+1只能y i或y i-1,使得步骤(4)的算法变得简单,只需做加法和乘4的乘法。
圆的Bresenham算法的程序实现如下:#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<graphics.h>void BresenhemCircle(int centerx, int centery, int radius, int color, int type);void initgr(void) /* BGI初始化*/{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/ initgraph(&gd, &gm, "");setbkcolor(WHITE);}int main(void){int centerx,centery,radius,color,type;printf("centerx,centery\n");scanf("%d",¢erx);scanf("%d",¢ery);printf("radius\n");scanf("%d",&radius);printf("color,type\n");scanf("%d",&color);scanf("%d",&type);initgr(); /*BGI初始化*/BresenhemCircle(centerx,centery,radius,color,type);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) {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);}else {line(centerx+x, centery+y, centerx+x, centery-y);line(centerx-x, centery+y, centerx-x, centery-y);}if (delta < 0) {if ((2*(delta+y)-1) < 0) {direction = 1;}else {direction = 2;}}else if(delta > 0) {if ((2*(delta-x)-1) <= 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;}}}二.中心画圆法圆的特性:八对称性。
只要扫描转换八分之一圆弧,就可以求出整个圆弧的像素集。
考虑中心在原点半径为R的第二个8分圆,构造判别式d=F(M)=(xp+1)2+(yp-0.5)2-R2若d<0则下一个像素为P1,而且再下一个象素的判别式为d=(Xp+2)2+(Yp-0.5)2-R2=d+2Xp+3若d>=0则下一个像素为P2,而且再下一个像素的判别式为d=(xp+2)2+(yp-1.5)2-R2=d+2(xp-yp)+5初值F(1,R-0.5)=1.25-R为了提高算法效率,可以将上面的浮点运算改为整数运算d0=1.25-R,用e=d-0.25代替d, e0=1-R,因为e为整数,所以e<-0.25等价于e<0,:算法描述:MidPointCircle(int x0, int y0, int r, int color){int x,y,d;x=0,y=r,d=1-r;drawpixel(x0,y0,x,y,color); //画圆上8个对称点while(x<=y){if(d<0) { d+=2*x+3; x++; }else { d+=2*(x-y)+5; x++; y--; }drawpixel(x0,y0,x,y,color); //画圆上8个对称点} /*while*/} /*MidPointCircle三.DDA算法若已知圆心坐标(xc ,yc),半径为r,则以角度t为参数的圆的参数方程可表示为:x=xc+r.cos t y=y c+r.sin t当t从0变化到2∏时,上述方程的轨迹是一整圆,当t从t s变化到t e时,产生一段圆弧(逆时针)。
产生这段圆弧最主要的问题是离散化圆弧,即求出运动的总步数n。
可令:n=(te -ts)/dt+0.5 其中,dt为角度增量,通常dt是根据半径r的大小来给定。
在实际应用中,应对速度和精度进行折中,并适当调整dt的大小,如果用户给定的te <ts,则可令te=ts+2∏,从而保证逆时针画圆,如果n=0,则令n=2∏/dt,即画整圆,为避免积累误差,最后应使t=te,强迫终止。
C语言的代码如下:arc(int xc,int yc,double r,double ts,double te){double rad,ts1,te1.deg,dte,ta,ct,st;int x,y,n,i;rad=0.0174533;ts1=ts*rad; te1=te*rad;if(r<5.08) deg=0.015;else if(r<7.62) deg=0.06;else if(r<25.4) deg=0.075;else deg=0.15;dte=deg*25.4/r;if(te1<ts1) te1+=6.28319;n=(int)((te1-ts1)/dte+0.5);if(n==0) n=(int)(6.28319/dte+0.5);ta=ts1;x=xc+r*cos(ts1); y=yc+r*sin(ts1);moveto(x,y);for(i=1;i<=n;i++){ta+=dte;ct=cos(ta);st=sin(ta);x=xc+r*ct;y=yc+r*st;lineto(x,y);} x=xc+r*cos(te1);y=yc+r*sin(te1);lineto(x,y);return(0);}在平面上给定3个点的坐标p1(x1,y1),p2(x2,y2),p3(x3,y3),我们就可以产生从p1到p3的一段圆弧,主要求出圆心坐标和半径以及p1和p3对应的角度ts与te。
根据三点坐标,可求出圆心坐标为:xc=(A(y3-y2)+B(y2-y1))/(2E) yc= (A(x2-x3)+B(x1-x2))/(2E) 其中:A=(x1+x2)(x1-x2)+(y1+y2)(y1-y2)B=(x3+x2)(x3-x2)+(y3+y2)(y3-y2)E=(x1-x2)(y3-y2)-(x2-x3)(y2-y1)若E=0,则产生一条p1到p3的直线,否则可求出半径如下:r2=(x1-xc)2+(y1-yc)2起点和终点对应的角度如下:ts=90°(当x1=xc时)或 tg-1((y1-yc)/(x1-xc)) ×57.2958°(当x1<>xc 时)te=90°(当x3=xc时)或 tg-1((y3-yc)/(x3-xc)) ×57.2958°(当x3<>xc 时)由于计算机提供的反正切函数计算的角度只是第一和第四象限的角度,所以应根据p1(或p3)相对于圆心位置是位于第二和第三象限,则由上式计算的值应加180°,考虑逆时针画圆,若te<ts,te应加360°。
运行结果:。