畫圓演算法
『壹』 怎樣用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;
}
『貳』 請問中點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();
}
運行效果:
『叄』 怎樣用利用Turbo C實現圓生成的中點畫圓演算法。
#include <glut.h>
#include <math.h>
#include <stdlib.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/glaux.h>
#include <Windows.h>
#pragma comment(lib,"glaux.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"glut32.lib")
#pragma comment(lib,"opengl32.lib")
class scrpt
{
public:
GLint x,y;
};
void myinit(void);
void display(void);
void setPixel(GLint x,GLint y);
void circlePlotPoint(scrpt circCtr,scrpt circpt);
void circleMidpoint(scrpt circCtr,GLint radius);
void setPixel(GLint x,GLint y)
{
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void myinit(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,800.0,0.0,600.0);
}
void circleMidpoint(scrpt circCtr,GLint radius)
{
scrpt circpt;
GLint p=1-radius;
circpt.x=0;
circpt.y=radius;
void circlePlotPoints(scrpt,scrpt);
circlePlotPoints(circCtr,circpt);
while(circpt.x<circpt.y)
{
circpt.x++;
if(p<0)
p+=2*circpt.x+1;
else
{
circpt.y--;
p+=2*(circpt.x-circpt.y)+1;
}
circlePlotPoints(circCtr,circpt);
}
}
void circlePlotPoints(scrpt circCtr,scrpt circpt)
{
setPixel(circCtr.x+circpt.x,circCtr.y+circpt.y);
setPixel(circCtr.x-circpt.x,circCtr.y-circpt.y);
setPixel(circCtr.x+circpt.x,circCtr.y-circpt.y);
setPixel(circCtr.x-circpt.x,circCtr.y+circpt.y);
setPixel(circCtr.x+circpt.y,circCtr.y+circpt.x);
setPixel(circCtr.x+circpt.y,circCtr.y-circpt.x);
setPixel(circCtr.x-circpt.y,circCtr.y+circpt.x);
setPixel(circCtr.x-circpt.y,circCtr.y-circpt.x);
}
void display(void)
{ scrpt point;
point.x=200;
point.y=210;
int radius=20;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.5,0.6,1.0);
circleMidpoint(point,radius);
glFlush();
}
void main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("pointcircle");
myinit();
glutDisplayFunc(display);
glutMainLoop();
}
『肆』 畫圓為什麼要用Bresenham演算法
演算法引入的本意是解決像素填充的問題的
點和線這種東西在理論上都是沒有寬度的,但是要在屏幕上繪制的時候就要去填充像素以形成痕跡
一行上經常有2個以上的像素都被線所貫穿, 如何填充是個問題
而且像素填充本身是使用非常頻繁的需求,故而畫線的演算法效率是非常重要的,對整個系統影響巨大
Bresenham演算法是通過增量計算的方式快速判別下一個行或者列上的要填充的像素的位置,從計算上來說非常的節省,幾乎都是整數的演算法,速度非常的快
『伍』 1.應用中點畫圓演算法,仿照AutoCAD做法,編寫用三點畫圓的程序(用vc編寫)。 2.應用中點畫圓演算法,編寫畫弧
發貨部分與推進會讓他
『陸』 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;
}
}
}
『柒』 求一個Java畫圓或橢圓演算法
所有點的坐標??沒搞明白!
『捌』 什麼是「直角坐標畫圓」演算法
就是根據圓心在直角坐標系裡的位置和半徑,依次計算
圓周
各點
坐標,並依次連接
這些點
「畫圓」
圓方程:
(x-x0)*(x-x0)
+
(y-y0)*(y-y0)
=
R*R
x0,y0
是圓心座標,R
是
半徑。
x
范圍是
x0-R
到
x0+R
y
范圍是
y0-R
到
y0+R
或:
(x-x0)
=
R
cos(A);
(y-y0)
=
R
sin(A);
你可以給一個步長(例如dA=1度),計算圓周
各點
的
坐標。
這就是
「直角坐標畫圓」演算法。
『玖』 中點畫圓演算法原理
圓心到圓上各點的距離相等(等於圓的半徑)
『拾』 計算機圖形學中集坐標畫圓的演算法
非常抱歉,俺不會...混分的,不用介意哦!