當前位置:首頁 » 操作系統 » 畫圓的演算法

畫圓的演算法

發布時間: 2022-04-30 06:28:04

Ⅰ C語言畫圓

把整個表格當作一個矩陣...
或者圓的直徑為邊長的正方形覆蓋的表格為矩陣...
或者用窮舉...滿足到圓心直線距離與半徑長的差在一定范圍內的點才保留...

Ⅱ 圓面積的演算法

圓的面積計算公式表示為S=πr²,其中π表示圓周率,r是半斤,而d表示直徑,已知一個圓的半徑或是長度,利用公式可計算出圓的面積,另外半圓的面積是πr²/2,周長為C=2πr或c=πd。

圓面積是指圓形所佔的平面空間大小,常用S表示。圓是一種規則的平面幾何圖形,其計算方法有很多種,比較常見的是開普勒的求解方法,卡瓦利里的求解方法等。

(2)畫圓的演算法擴展閱讀:

圓的性質

1、圓是軸對稱圖形,其對稱軸是任意一條通過圓心的直線。圓也是中心對稱圖形,其對稱中心是圓心。

2、垂徑定理:垂直於弦的直徑平分這條弦,並且平分弦所對的2條弧。

3、垂徑定理的逆定理:平分弦(不是直徑)的直徑垂直於弦,並且平分弦所對的2條弧。

Ⅲ 怎麼畫隋圓以及公式,

先固定兩個點,用釘子,然後用一根細線拴住筆畫就行了.
根據橢圓的數學定義:平面內與兩個定點F1、F2的距離之和等於常數(大於|F1F2|)的點的軌跡叫做橢圓,這兩個定點叫做橢圓的焦點,兩焦點間的距離c叫做焦距.你要在地上畫橢圓的步驟如下:
1.在地上筆直插兩根棍子,兩棍子間的距離為c = 2分子根3米(或者 0.866米);
2.找根2米長的繩子系在棍子兩端,最好貼著地系,保證系的兩端水平;
3.拿一支粉筆綳緊繩子,像畫圓一樣的畫,但是因為始終有繩子限制粉筆的軌跡,所以畫好後的圖形是一個橢圓(畫的過程要拿粉筆始終綳緊繩子).
橢圓的標准方程有兩種,取決於焦點所在的坐標軸:
1)焦點在X軸時,標准方程為:x^2/a^2+y^2/b^2=1 (a>b>0)
2)焦點在Y軸時,標准方程為:x^2/b^2+y^2/a^2=1 (a>b>0)

Ⅳ C語言用Bresenham演算法畫圓,哪位高手教教,主要是演算法里的內容,謝謝!

的確哈,關鍵在於對delta的理解
可以看到,都是delta=2*(1-radius)這樣的,起作用應該是判斷要畫的點x、y坐標的變化趨勢,先把我注釋了的代碼貼下,加了getch();可以看到畫的過程
-----------------------------------------------------------------
#include<graphics.h>
#include<stdio.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,15,0);
getch();
}

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();
}
/*以下代碼設置下次四點的位置,圓是對稱的,且此方法相當於同時畫四個圓弧
觀察右上方圓弧可知,前一半是x增的要快些,後一半是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 = 3; /*選擇縱向減*/
else
direction = 2;
}
else
direction=2;

switch(direction)
{
case 1:
x++;/*只橫坐標遠離原點*/
delta += (2*x+1); /*小執行到這,所以加*/
break;
case 2:
x++;
y--;/*橫向遠離,同時縱向靠近*/
delta += 2*(x-y+1); /*即(2*x+1)+(-2*y+1)*/
break;
case 3:
y--;/*只縱坐標靠近原點*/
delta += (-2*y+1); /*大執行到這,所以減*/
break;
}
}
}

Ⅳ 連續畫圓長度計算公式

你這個題目卻條件,比如畫圓的速度、
如果畫圓的周期為T,
那麼這種運動可以分解為三個運動,
x=Acos(2πt/T),
y=Asin(2πt/T),
z=Bt
然後畫第10個圓時,t=10T
利用曲線長度的求法
L=∫(0->10T)
√[(x't)^2+(y't)^2+(z't)^2]
dt
=∫(0->10T)
√[(2πA/T)^2+B^2]
dt
=10T√[(2πA/T)^2+B^2]

Ⅵ 畫圓的常見演算法

畫圓的基本演算法有逐點比較和DDA積分法,
代碼示例 WinC下運行

#include "Conio.h"
#include "graphics.h"
#include "process.h"
#define Ni_circle 0
#define Shun_circle 1
#define closegr closegraph

void initgr();
void draw_Base_circle();
void draw_cabu_circle();
void close_graph();
void acrroods();
static float x0,y0;

void initgr(void) /* BGI初始化 */
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同樣效果 */
registerbgidriver(EGAVGA_driver);/* 注冊BGI驅動後可以不需要.BGI文件的支持運行 */
initgraph(&gd, &gm, "");
}

void acrroods() /*屏幕中心坐標 */
{
x0=getmaxx()/2;
y0=getmaxy()/2;
}

void draw_Base_circle() /*畫圓及寫參數*/
{
line(x0-200,y0,x0+200,y0); outtextxy(x0+220,y0,"Z");
line(x0,y0-180,x0,y0+180); outtextxy(x0+10,y0+180,"X");
outtextxy(x0-10,y0+10,"O");
circle(x0,y0,150);
textcolor(YELLOW);
directvideo=0;
gotoxy(46,2);cprintf("Circle start:X0 Y0 Z150");
gotoxy(46,3);cprintf("Circle end :X0 Y0 Z150");
gotoxy(46,4);cprintf("Units :Pixel");
gotoxy(46,5);cprintf("Circle now:");
}

void close_graph() /*關圖形系統*/
{
closegraph();
}

void draw_cabu_circle(int sstep,int Directory)/*關鍵的圓插補函數*/
{
int flag=0;
float Fm,Xm,Ym;
Xm=x0+150; Ym=y0;
moveto(Xm,Ym);
setcolor(RED);
while(1) /*分象限,順圓和逆圓討論*/
{
Fm=(Xm-x0)/(Xm-x0)+(Ym-y0)/(Ym-y0)-150/150;/*圓判斷公式*/
if(Fm>=0){
if(!Directory){ /*逆圓判斷*/
if(Xm>=x0&&Ym<=y0)
{
if(flag) break; /*if語句判斷象限,以下一樣*/
else Xm=Xm-sstep;
}
if(Xm<=x0&&Ym<=y0)
{
flag=1; Ym=Ym+sstep;
}
if(Xm<=x0&&Ym>=y0)
Xm=Xm+sstep;
if(Xm>=x0&&Ym>=y0)
Ym=Ym-sstep;
}
else { /*it is Directory's else*/
if(Xm>x0&&Ym<y0)
Ym=Ym+sstep;
if(Xm<=x0&&Ym<=y0)
Xm=Xm+sstep;
if(Xm<x0&&Ym>y0) {
flag=1; Ym=Ym-sstep;}
if(Xm>=x0&&Ym>=y0) {
if(flag) break;
Xm=Xm-sstep;}
}
}
else{ /*it is Fm's else*/
if(!Directory) {
if(Xm>x0&&Ym<y0)
{
if(flag) break;
else Ym=Ym-sstep;
}
if(Xm<=x0&&Ym<=y0)
{
flag=1; Xm=Xm-sstep;
}
if(Xm<=x0&&Ym>=y0)
Ym=Ym+sstep;
if(Xm>=x0&&Ym>=y0)
Xm=Xm+sstep;
}
else{
if(Xm>x0&&Ym<y0)
Xm=Xm+sstep;
if(Xm<=x0&&Ym<=y0)
Ym=Ym-sstep;
if(Xm<=x0&&Ym>=y0){
flag=1; Xm=Xm-sstep;}
if(Xm>=x0&&Ym>=y0) {
if(flag) break;
else Ym=Ym+sstep;}
}
}
lineto(Xm,Ym);
gotoxy(58,5); printf("X%3.0f Y0 Z%3.0f ",Ym-y0,Xm-x0);
delay(800);
}
}

void circle_demo(int Directory) /*控制圓插補兩次*/
{
int i=0,sstep;
initgr(); /* BGI初始化 */
sleep(2);
acrroods(&x0,&y0);
for(i=0;i<2;i++)
{
draw_Base_circle(150);
if(i==0){
sstep=6;
draw_cabu_circle(sstep,Directory);}
else{
sstep=1;
draw_cabu_circle(sstep,Directory);}
getch();
cleardevice();
setcolor(WHITE);
}
}

/* 圓插補部分的函數區結束*/

int main(void)
{
int choice=0;
initgr(); /* BGI初始化 */

while(choice!=4)
{
setfillstyle(1,RED);
bar(200,30,400,80);
setcolor(GREEN);
settextstyle(3,0,10);
outtextxy(220,50,"DEMO PROGRAM BY P.Y.F");
setcolor(WHITE);
settextstyle(0,0,1);
outtextxy(200,140,"2. Shun_Circle demo.");
outtextxy(200,160,"3. Ni_Circle demo.");
outtextxy(200,180,"4. Quit the program.");
outtextxy(160,200,"Please enter your choice:"); gotoxy(46,13);
scanf("%d",&choice);

switch(choice)
{
case 2: circle_demo(Ni_circle);break;
case 3: circle_demo(Shun_circle);break;
case 4: break;
default: printf("\nChoice wrong,try again!");
}
}

getch(); /* 暫停一下,看看前面繪圖代碼的運行結果 */
closegr(); /* 恢復TEXT屏幕模式 */
return 0;
}

具體看看《計算機圖形學》。

Ⅶ 請問中點bresenham演算法畫圓與bresenham演算法畫圓有區別嗎

Bresenham演算法畫圓:

Bresenham演算法用來畫直線非常方便,但上次也說了,Bresenham演算法也可以用來顯示圓和其他曲線,只需要把直線方程改成圓方程或者其他曲線的方程就行,具體的推理過程就不演示了,大體跟直線的差不多!但由推算的結果可以看出,用Bresenham演算法來畫圓的確是不大明智的做法,要計算的步驟太多,計算速度比專門的畫圓方法慢很多!並且在斜率越大的地方像素的間距就越大,當然我們可以在畫某個像素之前先判斷一下這一點跟前面一點的連線的斜率,然後在適當的時候交換x、y的坐標,但這樣計算量必將增加!

直接給出Bresenham畫圓的代碼:

#include<gl/glut.h>

#include<math.h>

#include<stdio.h>

voiddraw_pixel(intix,intiy)

{

glBegin(GL_POINTS);

glVertex2i(ix,iy);

glEnd();

}

//intinlineround(constfloata){returnint(a+0.5);}

voidBresenham(intx1,inty1,intr,doublea,doubleb,doublec)/*圓心在(x1,y1),半徑為r的圓*/

{

glColor3f(a,b,c);

intdx=r;//intdy=abs(yEnd-y1);

//intp=2*dy-dx;

//inttwoDy=2*dy,twoDyMinusDx=2*dy-2*dx;

intx,y,d1,d2;

/*if(x1>xEnd)

{

x=xEnd;y=yEnd;

xEnd=x1;

}

else

{

x=x1;

y=y1;

}

*/

x=x1;

y=y1+r;

draw_pixel(x1,y1);

draw_pixel(x,y);//起始點裝入幀緩存,起始點是圓的最上面一點,然後按順時針來畫

while(x<=x1+dx)

{

d1=y1+sqrt(pow(r,2)-pow(x-x1,2));/*lower*/

x++;

d2=2*(y1+sqrt(pow(r,2)-pow(x-x1,2)))-2*d1-1;/*lower-upper*/

if(1)

{

y=d1;

draw_pixel(x,y);

draw_pixel(x,2*y1-y);

draw_pixel(2*x1-x,y);

draw_pixel(2*x1-x,2*y1-y);

}

else

{

y++;

//p+=twoDyMinusDx;

draw_pixel(x,y);

}

}

}

voiddisplay()

{

glClear(GL_COLOR_BUFFER_BIT);

Bresenham(250,250,200,0.0,0.0,1.0);

Bresenham(300,250,150,1.0,0.0,0.0);

Bresenham(200,250,150,0.0,1.0,0.0);

//Bresenham(250,300,150,0.8,0.4,0.3);

//Bresenham(250,200,150);

glFlush();

}

voidmyinit()

{

glClearColor(0.8,1.0,1.0,1.0);

//glColor3f(0.0,0.0,1.0);

glPointSize(1.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,500.0,0.0,500.0);

}

voidmain(intargc,char**argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowSize(500,500);

glutInitWindowPosition(200.0,200.0);

glutCreateWindow("CG_test_Bresenham_Circleexample");

glutDisplayFunc(display);

myinit();

glutMainLoop();

}

以下為程序運行效果:

中點畫圓:

用光柵畫圓的不足在上次已經用實例表示的很明白了,上次畫的那個圓怎麼都不能算滿意,雖然可以通過修改演算法來得到改善,但本來計算步驟就已經很多了,交換坐標重新計算將會大大增加計算機的就是負擔,為此我們採用另一種更加常用的畫圓演算法——中點畫圓演算法,之所以叫做「中點」畫圓演算法是由於它不是像Bresenham演算法那樣所繪像素不是(xk+1,yk)就是(xk+1,yk+1),而是根據這兩個點的中點來判斷是(xk+1,yk)還是(xk+1,yk-1)更接近於圓!

對於給定的半徑r和圓心(x0,y0),我們先計算圓心在原點(0,0)的點,然後將其平移到圓心(x0,y0)處即可,跟Bresenham演算法一樣,我們也可以藉助圓的高度對稱性來減少計算機的計算步驟,在這里我們可以先計算出八分之一圓的像素點,然後根據對稱性繪出其他點。這樣可以大大加快畫圓的速度!

跟光柵化方法一樣,我們還是採用步進的方法來逐點描繪,但這里的決策參數計算方式跟Bresenham不大一樣,設決策參數為p,則:

P=x2+y2-r2

對於任一個點(x,y),可以根據p的符號來判斷點是在圓內還是圓外還是在圓上,這里不多說,假設我們在(xk,yk)處繪制了一個像素,下一步需要確定的是(xk+1,yk)還是(xk+1,yk-1)更接近於圓,在此代入這兩個點的中點來求出決策參數:

Pk=(xk+1)2+(yk-1/2)2-r2

如果Pk<0,則yk上的像素更接近於圓,否則就是yk-1更接近於圓

同理可以推出Pk+1=Pk+2(xk+1)+(yk+12-yk2)-(yk+1-yk)+1

給出一個示例,這個圓比用Bresenham畫出來的好看多了:

#include<glglut.h>

classscreenPt

{

private:

intx,y;

public:

screenPt(){x=y=0;}

voidsetCoords(GLintxCoordValue,GLintyCoordValue)

{

x=xCoordValue;

y=yCoordValue;

}

GLintgetx()const

{

returnx;

}

GLintgety()const

{

returny;

}

voidincrementx(){x++;}

voiddecrementy(){y--;}

};

voiddraw_pixel(intxCoord,intyCoord)

{

glBegin(GL_POINTS);

glVertex2i(xCoord,yCoord);

glEnd();

}

voidcircleMidpoint(GLintxc,GLintyc,GLintradius)

{

screenPtcircPt;

GLintp=1-radius;

circPt.setCoords(0,radius);

voidcirclePlotPoints(GLint,GLint,screenPt);

circlePlotPoints(xc,yc,circPt);

while(circPt.getx()<circPt.gety())

{

circPt.incrementx();

if(p<0)

p+=2*circPt.getx()+1;

else

{

circPt.decrementy();

p+=2*(circPt.getx()-circPt.gety())+1;

}

circlePlotPoints(xc,yc,circPt);

}

}

voidcirclePlotPoints(GLintxc,GLintyc,screenPtcircPt)//描繪八分圓各點

{

draw_pixel(xc+circPt.getx(),yc+circPt.gety());

draw_pixel(xc-circPt.getx(),yc+circPt.gety());

draw_pixel(xc+circPt.getx(),yc-circPt.gety());

draw_pixel(xc-circPt.getx(),yc-circPt.gety());

draw_pixel(xc+circPt.gety(),yc+circPt.getx());

draw_pixel(xc-circPt.gety(),yc+circPt.getx());

draw_pixel(xc+circPt.gety(),yc-circPt.getx());

draw_pixel(xc-circPt.gety(),yc-circPt.getx());

}

voiddisplay()

{

//screenPtPt;

glClear(GL_COLOR_BUFFER_BIT);

circleMidpoint(250,250,200);

glFlush();

}

voidmyinit()

{

glClearColor(0.8,1.0,1.0,1.0);

glColor3f(0.0,0.0,1.0);

glPointSize(1.0);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluOrtho2D(0.0,500.0,0.0,500.0);

}

voidmain(intargc,char**argv)

{

glutInit(&argc,argv);

glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);

glutInitWindowSize(500,500);

glutInitWindowPosition(200.0,200.0);

glutCreateWindow("CG_test_中點畫圓example");

glutDisplayFunc(display);

myinit();

glutMainLoop();

}

運行效果:

Ⅷ 怎樣用C語言畫圓

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
char arg[50]={0};
arg[0]= '\ " ';
strcpy(arg+1,argv[0]);
int len=int(strlen(arg));
arg[len]= '\ " ';

HWND hWnd=FindWindow(NULL,arg); //找到程序運行窗口的句柄
HDC hDC=GetDC(hWnd);//通過窗口句柄得到該窗口的設備場境句柄
HPEN hPen,hOldPen; //畫筆
int i=0;

for(;i <500;++i)
SetPixel(hDC,10+i,10+i,0x0000ff);//用畫點的辦法畫一根線,最後一個參數是顏色(32位)

hPen=CreatePen(PS_SOLID,2,0x00ff00);//生成綠色畫筆
hOldPen=(HPEN)SelectObject(hDC,hPen);//把畫筆引入設備場境

MoveToEx(hDC,20,50,NULL); //設置畫線起點
LineTo(hDC,520,550); //畫到終點

Arc(hDC,100,100,300,300,350,500,350,500);//畫圓

SelectObject(hDC,hOldPen);
ReleaseDC(hWnd,hDC);

//下面是對比,表明它確實是控制台程序

printf( "hello console ");
system( "pause ");
return 0;

}

Ⅸ 畫圓的公式

C=1/2×2πR+2R=1/2×2π×52+2×52=52π+104總長是C,厄……不會是154吧!

熱點內容
小說分銷系統源碼 發布:2024-10-05 07:13:54 瀏覽:631
主板能存儲數據嗎 發布:2024-10-05 07:13:22 瀏覽:89
安卓文件管理器在哪裡打開手機 發布:2024-10-05 07:12:19 瀏覽:224
個人網站源碼html 發布:2024-10-05 06:59:47 瀏覽:409
安卓fc下載游戲在哪個文件夾 發布:2024-10-05 06:51:05 瀏覽:765
演算法狼人殺 發布:2024-10-05 06:50:21 瀏覽:346
ibm伺服器怎麼做raid5 發布:2024-10-05 06:46:20 瀏覽:854
wifi如何換密碼 發布:2024-10-05 06:25:39 瀏覽:549
ubuntu遠程訪問mysql 發布:2024-10-05 06:17:29 瀏覽:223
centos配置後怎麼做 發布:2024-10-05 06:08:59 瀏覽:70