画圆形算法
A. 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;
}
}
}
B. matlab如何画圆
使用MATLAB画圆的方法有两种,分别如下:
1、启动MATLAB,新建脚本,输入以下代码:
close all; clear all; clc
r=2; theta=0:pi/100:2*pi;
x=r*cos(theta); y=r*sin(theta);
rho=r*sin(theta);
figure(1)
plot(x,y,'-')
hold on; axis equal
fill(x,y,'c')
figure(2)
h=polar(theta,rho);
set(h,'LineWidth',2)
C. 怎样用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;
}
D. 怎样画圆
是不是编程题?
#include <windows.h>
#include <stdio.h>
#include <math.h>
typedef struct
{
HWND *lphWnd;
DWORD dwExStyle; // extended window style
LPCTSTR lpClassName; // pointer to registered class name
LPCTSTR lpWindowName; // pointer to window name
DWORD dwStyle; // window style
int x; // horizontal position of window
int y; // vertical position of window
int nWidth; // window width
int nHeight; // window height
HMENU hMenu; // handle to menu, or child-window identifier
}childstru;
HANDLE hInst;
HFONT hFont;
HWND MainhWnd,button1,button2,button3,button4;
HDC mDc;
HBITMAP hbmp;
char *titletext="两种画圆算法",*classname="HeLiang";
BOOL InitApplication(HANDLE hInstance);
BOOL InitInstance(HANDLE hInstance,int nCmdShow);
//------------------------------------------------
childstru CldWin[]=
{
{
&button1,
0,// extended window style
"Button",// pointer to registered class name
"Midpoint",// pointer to window name
WS_VISIBLE| WS_CHILD |BS_PUSHBUTTON,// window style
0,// horizontal position of window
0,// vertical position of window
80,// window width
21,// window height
NULL,// handle to menu, or child-window identifier
},
{
&button2,
0,// extended window style
"Button",// pointer to registered class name
"Bresenham",// pointer to window name
WS_VISIBLE| WS_CHILD |BS_PUSHBUTTON,// window style
0,// horizontal position of window
0,// vertical position of window
80,// window width
21,// window height
NULL,// handle to menu, or child-window identifier
},
{
&button3,
0,// extended window style
"Button",// pointer to registered class name
"Clear",// pointer to window name
WS_VISIBLE| WS_CHILD |BS_PUSHBUTTON,// window style
0,// horizontal position of window
0,// vertical position of window
80,// window width
21,// window height
NULL,// handle to menu, or child-window identifier
},
{
&button4,
0,// extended window style
"Button",// pointer to registered class name
"Line",// pointer to window name
WS_VISIBLE| WS_CHILD |BS_PUSHBUTTON,// window style
0,// horizontal position of window
0,// vertical position of window
80,// window width
21,// window height
NULL,// handle to menu, or child-window identifier
},
{
NULL,
0,// extended window style
NULL,// pointer to registered class name
NULL,// pointer to window name
0,// window style
0,// horizontal position of window
0,// vertical position of window
0,// window width
0,// window height
NULL,// handle to menu, or child-window identifier
}
};
//------------------------------------------------
void __fastcall MidLine(HDC hDc,int x0,int y0,int x1,int y1,COLORREF color)
{
int a,b,dt1,dt2,d,x,y,ystp=1;
if(abs(x1-x0)>abs(y1-y0))
{
if(x0>x1)
{
x=x0;x0=x1;x1=x;
y=y0;y0=y1;y1=y;
}
a=y0-y1;
b=x1-x0;
if(a>0){a=-a;ystp=-1;}else ystp=1;
d=(a<<1)+b;
dt1=a<<1;
dt2=(a+b)<<1;
x=x0;
y=y0;
SetPixel(hDc,x,y,color);
while(x<x1)
{
if(d<0)
{
x++;y+=ystp;d+=dt2;
}else
{
x++;
d+=dt1;
}
SetPixel(hDc,x,y,color);
}
}else
{
if(y0>y1)
{
x=x0;x0=x1;x1=x;
y=y0;y0=y1;y1=y;
}
a=x0-x1;
b=y1-y0;
if(a>0){a=-a;ystp=-1;}else ystp=1;
d=(a<<1)+b;
dt1=a<<1;
dt2=(a+b)<<1;
x=x0;
y=y0;
SetPixel(hDc,x,y,color);
while(y<y1)
{
if(d<0)
{
y++;x+=ystp;d+=dt2;
}else
{
y++;
d+=dt1;
}
SetPixel(hDc,x,y,color);
}
}
}
//------------------------------------------------
void __fastcall cirpixel(HDC hDc,int x0,int y0,int x,int y,COLORREF color)
{
SetPixel(hDc,x0+x,y0+y,color);
SetPixel(hDc,x0+y,y0+x,color);
SetPixel(hDc,x0-x,y0+y,color);
SetPixel(hDc,x0+y,y0-x,color);
SetPixel(hDc,x0+x,y0-y,color);
SetPixel(hDc,x0-y,y0+x,color);
SetPixel(hDc,x0-x,y0-y,color);
SetPixel(hDc,x0-y,y0-x,color);
}
//------------------------------------------------
void __fastcall bpixel(HDC hDc,int x0,int y0,int x,int y,COLORREF color)
{
SetPixel(hDc,x0+x,y0+y,color);
SetPixel(hDc,x0-x,y0+y,color);
SetPixel(hDc,x0+x,y0-y,color);
SetPixel(hDc,x0-x,y0-y,color);
}
//------------------------------------------------
void __fastcall BresenhamCircle(HDC hDc,int x0,int y0,int r,COLORREF color)
{
int x,y,dt,dt1,dt2,dr;
x=0;y=r;dt=2-r-r;
while(y>=0)
{
bpixel(hDc,x0,y0,x,y,color);
if(dt<0)
{
dt1=dt+dt+y+y-1;
if(dt1<=0)dr=1;
else dr=2;
}
else if(dt>0)
{
dt2=dt+dt-x-x-1;
if(dt2<=0)dr=2;
else dr=3;
}else dr=2;
switch(dr)
{
case 1: x++;dt+=x+x+1;
break;
case 2: x++;y--;dt+=x+x-y-y-1;
break;
case 3: y--;dt+=1-y-y;
break;
}
}
}
//------------------------------------------------
void __fastcall MidpointCircle(HDC hDc,int x,int y,int r,COLORREF color)
{
int xx,yy,dtx,dty,d;
xx=0;yy=r;dtx=3,dty=2-r-r;d=1-r;
cirpixel(hDc,x,y,xx,yy,color);
while(xx<yy)
{
if(d<0)
{
d+=dtx;dtx+=2;xx++;
}else
{
d+=dtx+dty;dtx+=2;dty+=2;xx++;yy--;
}
cirpixel(hDc,x,y,xx,yy,color);
}
}
//------------------------------------------------
long PASCAL MainWnProc(HWND hWnd,unsigned int Message,unsigned int wParam,long lParam)
{
static HANDLE hDc;
RECT rect;
PAINTSTRUCT ps;
WNDPROC prevWinProc;
int i;
switch(Message)
{
case WM_CREATE:
SendMessage(hWnd,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(true, 0));
i=0;
while(CldWin[i].lphWnd!=NULL)
{
*(CldWin[i].lphWnd)=CreateWindowEx(CldWin[i].dwExStyle,CldWin[i].lpClassName,
CldWin[i].lpWindowName,CldWin[i].dwStyle,CldWin[i].x,CldWin[i].y,
CldWin[i].nWidth,CldWin[i].nHeight,hWnd,CldWin[i].hMenu,hInst,NULL);
SendMessage(*(CldWin[i].lphWnd),WM_SETFONT,(WPARAM)hFont,MAKELPARAM(true, 0));
i++;
}
return 0;
case WM_PAINT:
hDc=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
return 0;
case WM_SIZE:
GetClientRect(hWnd,&rect);
MoveWindow(button1,rect.right-240,rect.bottom-30,70,21,true);
MoveWindow(button2,rect.right-160,rect.bottom-30,70,21,true);
MoveWindow(button3,rect.right-80,rect.bottom-30,70,21,true);
MoveWindow(button4,rect.right-320,rect.bottom-30,70,21,true);
InvalidateRect(hWnd,NULL,true);
break;
case WM_COMMAND:
if(LOWORD(lParam)==(unsigned short)button1)
{
hDc=GetDC(MainhWnd);
for(int r=200;r>=0;r--)
MidpointCircle(hDc,260,260,r,RGB(255,0,0xff-r));
MidpointCircle(hDc,260,260,250,RGB(255,0,250));
ReleaseDC(MainhWnd,hDc);
}
if(LOWORD(lParam)==(unsigned short)button2)
{
hDc=GetDC(MainhWnd);
for(int r=200;r>=0;r--)
BresenhamCircle(hDc,260,260,r,RGB(255,0xff-r,0));
BresenhamCircle(hDc,260,260,250,RGB(255,250,0));
ReleaseDC(MainhWnd,hDc);
}
if(LOWORD(lParam)==(unsigned short)button4)
{
hDc=GetDC(MainhWnd);
for(int i=0;i<700;i++)
MidLine(hDc,300,200,i,50,RGB(255,0,i*255/700));
for(int i=0;i<700;i++)
MidLine(hDc,300,200,i,350,RGB(i*255/700,255,0));
for(int i=50;i<350;i++)
MidLine(hDc,300,200,0,i,RGB(0,255,i*255/350));
for(int i=50;i<350;i++)
MidLine(hDc,300,200,700,i,RGB(0,i*255/350,255));
ReleaseDC(MainhWnd,hDc);
}
if(LOWORD(lParam)==(unsigned short)button3)
{
InvalidateRect(hWnd,NULL,true);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,Message,wParam,lParam);
}
//------------------------------------------------
int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
LOGFONT LogFont;
MSG msg;
HDC hDc;
hFont=GetStockObject(DEFAULT_GUI_FONT);
if(!hPrevInstance)
if(!InitApplication(hInstance)) return (FALSE);
if(!InitInstance(hInstance,nCmdShow)) return(FALSE);
while(GetMessage(&msg,NULL,NULL,NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DeleteObject(hFont);
return(msg.wParam);
}
//------------------------------------------------
BOOL InitApplication(HANDLE hInstance)
{
WNDCLASS wc;
wc.style=NULL;
wc.lpfnWndProc=MainWnProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(hInstance,"MAINICON");
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName=""; //Name of menu resource in .RC file
wc.lpszClassName=classname; //Name used in call to CreateWindow.
return RegisterClass(&wc);
}
//------------------------------------------------
BOOL InitInstance(HANDLE hInstance,int nCmdShow)
{
HWND hWnd;
hInst=hInstance;
hWnd=CreateWindowEx(WS_EX_APPWINDOW,classname,titletext,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
MainhWnd=hWnd;
if(!hWnd)return(FALSE);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return(TRUE);
}
//------------------------------------------------
E. C++画圆(计算机图形学)
#include<math.h>
#include<graphics.h>/*预定义库函数*/
voidcirclePoint(intx,inty)/*八分法画圆程序*/
{
circle(320x*20,240y*20,3);
circle(320y*20,240x*20,3);
circle(320-y*20,240x*20,3);
circle(320-x*20,240y*20,3);
circle(320-x*20,240y*20,3);
circle(320-x*20,240-y*20,3);
circle(320-y*20,240-x*20,3);
circle(320y*20,240-x*20,3);
circle(320x*20,240-y*20,3);
}
voidMidBresenhamcircle(intr)/*中点Bresenham算法画圆的程序*/
{
intx,y,d;
x=0;y=r;d=1-r;/*计算初始值*/
while(x<y)
{circlePoint(x,y);/*绘制点(x,y)及其在八分圆中的另外7个对称点*/
if(d<0)d=2*x3;/*根据误差项d的判断,决定非最大位移方向上是走还是不走*/
else
{d=2*(x-y)5;
y--;
}
x;
delay(900000);
}/*while*/
}
main()
{
inti,j,r,graphmode,graphdriver;
detectgraph(&graphdriver,&graphmode);
initgraph(&graphdriver,&graphmode,"");
printf("中点Bresenhamcircle算法画圆的程序 ");/*提示信息*/
printf("注意|r|<=11");
printf(" 输入半径值r:");
scanf("%d",&r);
printf("按任意键显示图形...");
getch();
cleardevice();
setbkcolor(BLACK);
for(i=20;i<=620;i=20)/*使用双循环画点函数画出表格中的纵坐标*/
for(j=20;j<=460;j)
putpixel(i,j,2);
for(j=20;j<=460;j=20)/*使用双循环画点函数画出表格中的横坐标*/
for(i=20;i<=620;i)
putpixel(i,j,2);
outtextxy(320,245,"0");/*原点坐标*/
outtextxy(320-5*20,245,"-5");circle(320-5*20,240,2);/*横坐标值*/
outtextxy(3205*20,245,"5");circle(3205*20,240,2);
outtextxy(320-10*20,245,"-10");circle(320-10*20,240,2);
outtextxy(32010*20,245,"10");circle(32010*20,240,2);
outtextxy(320-15*20,245,"-15");circle(320-15*20,240,2);
outtextxy(32015*20,245,"15");circle(32015*20,240,2);
outtextxy(320,240-5*20,"-5");circle(320,240-5*20,2);/*纵坐标值*/
outtextxy(320,2405*20,"5");circle(320,2405*20,2);
outtextxy(320,240-10*20,"-10");circle(320,240-10*20,2);
outtextxy(320,24010*20,"10");circle(320,24010*20,2);
outtextxy(20,10,"Thecenterofthecircleis(0,0)");/*坐标轴左上角显示提示信息*/
setcolor(RED);/*标记坐标轴*/
line(20,240,620,240);outtextxy(32015*20,230,"X");
line(320,20,320,460);outtextxy(330,20,"Y");
setcolor(YELLOW);
MidBresenhamcircle(r);
setcolor(BLUE);/*绘制圆*/
circle(320,240,r*20);
setcolor(2);
getch();
closegraph();
}
F. c语言中如何用line画一个圆
#include <math.h>
#include <graphics.h> /*预定义库函数*/
void circlePoint(int x,int y) /*八分法画圆程序*/
{
circle(320+x*20,240+y*20,3);
circle(320+y*20,240+x*20,3);
circle(320-y*20,240+x*20,3);
circle(320-x*20,240+y*20,3);
circle(320-x*20,240+y*20,3);
circle(320-x*20,240-y*20,3);
circle(320-y*20,240-x*20,3);
circle(320+y*20,240-x*20,3);
circle(320+x*20,240-y*20,3);
}
void MidBresenhamcircle(int r) /* 中点Bresenham算法画圆的程序 */
{
int x,y,d;
x=0;y=r;d=1-r; /* 计算初始值 */
while(x<y)
{ circlePoint(x,y); /* 绘制点(x,y)及其在八分圆中的另外7个对称点 */
if(d<0) d+=2*x+3; /* 根据误差项d的判断,决定非最大位移方向上是走还是不走 */
else
{ d+=2*(x-y)+5;
y--;
}
x++;
delay(900000);
} /* while */
}
main()
{
int i,j,r,graphmode,graphdriver;
detectgraph(&graphdriver,&graphmode); initgraph(&graphdriver,&graphmode," ");
printf("中点Bresenhamcircle算法画圆的程序\n"); /*提示信息*/
printf("注意 |r|<=11");
printf("\n输入半径值 r:");
scanf("%d",&r);
printf("按任意键显示图形...");
getch(); cleardevice(); setbkcolor(BLACK);
for(i=20;i<=620;i+=20) /*使用双循环画点函数画出表格中的纵坐标*/
for(j=20;j<=460;j++)
putpixel(i,j,2);
for(j=20;j<=460;j+=20) &n欢迎光临学网,收藏本篇文章 [1] [2]
$False$
bsp; /*使用双循环画点函数画出表格中的横坐标*/
for(i=20;i<=620;i++)
putpixel(i,j,2); outtextxy(320,245,"0"); /*原点坐标*/
outtextxy(320-5*20,245,"-5");circle(320-5*20,240,2); /*横坐标值*/
outtextxy(320+5*20,245,"5");circle(320+5*20,240,2);
outtextxy(320-10*20,245,"-10");circle(320-10*20,240,2);
outtextxy(320+10*20,245,"10");circle(320+10*20,240,2);
outtextxy(320-15*20,245,"-15");circle(320-15*20,240,2);
outtextxy(320+15*20,245,"15");circle(320+15*20,240,2);
outtextxy(320,240-5*20,"-5");circle(320,240-5*20,2); /*纵坐标值*/
outtextxy(320,240+5*20,"5");circle(320,240+5*20,2);
outtextxy(320,240-10*20,"-10");circle(320,240-10*20,2);
outtextxy(320,240+10*20,"10");circle(320,240+10*20,2);
outtextxy(20,10,"The center of the circle is (0,0) "); /*坐标轴左上角显示提示信息*/
setcolor(RED); /*标记坐标轴*/
line(20,240,620,240); outtextxy(320+15*20,230,"X");
line(320,20,320,460); outtextxy(330,20,"Y");
setcolor(YELLOW);
MidBresenhamcircle(r);
setcolor(BLUE); /*绘制圆*/
circle(320,240,r*20);
setcolor(2);
getch(); closegraph();
}
G. 用C语言写出画一个圆形的代码
可以参考下面的代码:
#include<math.h>
main()
{
double y;
int x,m;
for(y=10;y>=-10;y--)
{
m=2.5*sqrt(100-y*y);
for(x=1;x<50-m;x++)
printf(" ");
printf("*");
for(;x<50+m;x++)
printf(" ");
printf("* ");
}
}
(7)画圆形算法扩展阅读:
for循表达式为:for(单次表达式;条件表达式;末尾循环体){中间循环体;}。
其中,表示式皆可以省略,但分号不可省略,因为“;”可以代表一个空语句,省略了之后语句减少,即为语句格式发生变化,则编译器不能识别而无法进行编译。for循环小括号里第一个“;”号前为一个为不参与循环的单次表达式。
H. 请问中点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();
}
运行效果:
I. 急求C语言中怎样画一个圆形图形
#include<stdlib.h>
#include<graphics.h>
int main()
{
int gdriver, gmode, i;
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\caic\\bgi");
setbkcolor(BLUE);/*设背景颜色*/
cleardevice();
setcolor(12); /*设置作图颜色*/
arc(100, 100, 0, 360, 50); /*画一个以(100,100)为圆心,50为半径,从0度到360度的圆*/
getch();
closegraph();
return 0;
}
/*turbo c2.0下编译通过*/
J. 什么是“直角坐标画圆”算法
就是根据圆心在直角坐标系里的位置和半径,依次计算
圆周
各点
坐标,并依次连接
这些点
“画圆”
圆方程:
(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度),计算圆周
各点
的
坐标。
这就是
“直角坐标画圆”算法。