计算机图形学Bresenham完整算法画直线椭圆和圆.docx
《计算机图形学Bresenham完整算法画直线椭圆和圆.docx》由会员分享,可在线阅读,更多相关《计算机图形学Bresenham完整算法画直线椭圆和圆.docx(15页珍藏版)》请在冰豆网上搜索。
计算机图形学Bresenham完整算法画直线椭圆和圆
计算机图形学--Bresenham完整算法-画直线、椭圆和圆
#include
#include
#include"stdio.h"
intm_PointNumber=0;//动画时绘制点的数目
intm_DrawMode=1;//绘制模式1DDA算法画直线
//2中点Bresenham算法画直线
//3改进Bresenham算法画直线
//4八分法绘制圆
//5四分法绘制椭圆
//绘制坐标线
voidDrawCordinateLine(void)
{
inti=-250;
//坐标线为黑色
glColor3f(0.0f,0.0f,0.0f);
glBegin(GL_LINES);
for(i=-250;i<=250;i=i+10)
{
glVertex2f((float)(i),-250.0f);
glVertex2f((float)(i),250.0f);
glVertex2f(-250.0f,(float)(i));
glVertex2f(250.0f,(float)(i));
}
glEnd();
}
//绘制一个点,这里用一个正方形表示一个点
voidputpixel(GLsizeix,GLsizeiy)
{
glRectf(10*x,10*y,10*x+10,10*y+10);
}
///////////////////////////////////////////////////////////////////
//DDA画线算法//
////
////
////
///////////////////////////////////////////////////////////////////
voidDDACreateLine(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1,GLsizeinum)
{
//设置颜色
glColor3f(1.0f,0.0f,0.0f);
//对画线动画进行控制
if(num==1)
printf("DDA画线算法:
各点坐标\n");
elseif(num==0)
return;
//画线算法的实现
GLsizeidx,dy,epsl,k;
GLfloatx,y,xIncre,yIncre;
dx=x1-x0;
dy=y1-y0;
x=x0;
y=y0;
if(abs(dx)>abs(dy))epsl=abs(dx);
elseepsl=abs(dy);
xIncre=(float)dx/epsl;
yIncre=(float)dy/epsl;
for(k=0;k<=epsl;k++){
putpixel((int)(x+0.5),(int)(y+0.5));
if(k>=num-1){
printf("x=%f,y=%f,取整后x=%d,y=%d\n",x,y,(int)(x+0.5),(int)(y+0.5));
break;
}
x+=xIncre;
y+=yIncre;
if(x>=25||y>=25)break;
}
}
///////////////////////////////////////////////////////////////////
//中点Bresenham算法画直线(0<=k<=1)//
////
////
////
///////////////////////////////////////////////////////////////////
voidBresenhamLine(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1,GLsizeinum)
{
glColor3f(1.0f,0.0f,0.0f);
if(num==1)
printf("中点Bresenham算法画直线各点坐标及判别式的值\n");
elseif(num==0)
return;
//画线算法的实现
GLsizeip=0;
GLfloatUpIncre,DownIncre,x,y,d,k,dx,dy;
if(x0>x1){
x=x1;x1=x0;x0=x;
y=y1;y1=y0;y0=y;
}
x=x0;y=y0;
dx=x1-x0;dy=y1-y0;
k=dy/dx;
if(k>=0&&k<=1){
d=dx-2*dy;
UpIncre=2*dx-2*dy;
DownIncre=-2*dy;
while(x<=x1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
x++;
if(d<0){
y++;
d+=UpIncre;
}
elsed+=DownIncre;
}
}
if(k>1){
d=dy-2*dx;
UpIncre=2*dy-2*dx;
DownIncre=-2*dx;
while(y<=y1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
y++;
if(d<0){
x++;
d+=UpIncre;
}
elsed+=DownIncre;
}
}
if(k<0&&k>=-1){
d=dx-2*dy;
UpIncre=-2*dy;
DownIncre=-2*dx-2*dy;
while(x<=x1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
x++;
if(d>0){
y--;
d+=DownIncre;
}
elsed+=UpIncre;
}
}
if(k<-1){
d=-dy-2*dx;
UpIncre=-2*dx-2*dy;
DownIncre=-2*dx;
while(y>=y1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
y--;
if(d<0){
x++;
d+=UpIncre;
}
elsed+=DownIncre;
}
}
}
///////////////////////////////////////////////////////////////////
//改进的Bresenham算法画直线(0<=k<=1)//
////
//x1,y1终点坐标//
////
///////////////////////////////////////////////////////////////////
voidBresenham2Line(GLsizeix0,GLsizeiy0,GLsizeix1,GLsizeiy1,GLsizeinum)
{
glColor3f(1.0f,0.0f,0.0f);
GLsizeix,y,dx,dy,e,k;
if(num==1)
printf("改进的Bresenham算法画直线各点坐标及判别式的值\n");
elseif(num==0)
return;
//画线算法的实现
GLsizeip=0;
if(x0>x1){
x=x1;x1=x0;x0=x;
y=y1;y1=y0;y0=y;
}
dx=x1-x0;dy=y1-y0;
k=dy/dx;
if(k>=0&&k<=1){
e=-dx;x=x0;y=y0;
while(x<=x1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
x++;
e=e+2*dy;
if(e>0){
y++;
e=e-2*dx;
}
}
}
if(k>1){
e=-dy;x=x0;y=y0;
while(y<=y1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
y++;
e=e+2*dx;
if(e>0){
x++;
e=e-2*dy;
}
}
}
if(k<0&&k>=-1){
e=-dx;x=x0;y=y0;
while(x<=x1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
x++;
e=e+2*dy;
if(e<0){
y--;
e=e+2*dx;
}
}
}
if(k<-1){
e=-dy;x=x0;y=y0;
while(y>=y1){
putpixel(x,y);
if(p>=num-1){
printf("x=%d,y=%d\n",x,y);
break;
}
p++;
y--;
e=e-2*dx;
if(e<0){
x++;
e=e-2*dy;
}
}
}
}
/////////////////////////////////////////////////////////
//Bresenham算法画圆//
////
////
////
/////////////////////////////////////////////////////////
voidCirclePoint(GLsizeix,GLsizeiy)
{putpixel(x,y);
putpixel(x,-y);
putpixel(y,-x);
putpixel(-y,-x);
putpixel(-x,-y);
putpixel(-x,y);
putpixel(-y,x);
putpixel(y,x);
}
voidBresenhamCircle(GLsizeix,GLsizeiy,GLsizeiR,GLsizeinum)
{
glColor3f(1.0f,0.0f,0.0f);
GLsizeid;
x=0;y=R;d=1-R;
if(num==1)
printf("Bresenham算法画圆:
各点坐标及判别式的值\n");
elseif(num==0)
return;
while(x<=y){
CirclePoint(x,y);
if(x>=num-1){
printf("x=%d,y=%d,d=%d\n",x,y,d);
break;
}
if(d<0)d+=2*x+3;
else{
d+=2*(x-y)+5;
y--;
}
x++;
}
}
voidBresenham2Circle(GLsizeia,GLsizeib,GLsizeinum)
{
glColor3f(1.0f,0.0f,0.0f);
if(num==1)
printf("Bresenham算法画椭圆:
各点坐标及判别式的值\n");
elseif(num==0)
return;
GLsizeix,y;
floatd1,d2;
x=0;y=b;
d1=b*b+a*a*(-b+0.5);
putpixel(x,y);putpixel(-x,-y);
putpixel(-x,y);putpixel(x,-y);
while(b*b*(x+1)if(x>=num-1){
printf("x=%d,y=%d,d1=%d\n",x,y,d1);
break;
}
if(d1<=0){
d1+=b*b*(2*x+3);
x++;
}
else{
d1+=b*b*(2*x+3)+a*a*(-2*y+2);
x++;y--;
}
putpixel(x,y);putpixel(-x,-y);
putpixel(-x,y);putpixel(x,-y);
}//while上半部分
d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;
while(y>0){
if(x>=num-1){
printf("x=%d,y=%d,d2=%d\n",x,y,d2);
break;
}
if(d2<=0){
d2+=b*b*(2*x+2)+a*a*(-2*y+3);
x++;y--;
}
else{
d2+=a*a*(-2*y+3);
y--;
}
putpixel(x,y);putpixel(-x,-y);
putpixel(-x,y);putpixel(x,-y);
}
}
//初始化窗口
voidInitial(void)
{
//设置窗口颜色为蓝色
glClearColor(0.0f,0.0f,1.0f,1.0f);
}
//窗口大小改变时调用的登记函数
voidChangeSize(GLsizeiw,GLsizeih)
{
if(h==0)h=1;
//设置视区尺寸
glViewport(0,0,w,h);
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修剪空间的范围
if(w<=h)
glOrtho(-250.0f,250.0f,-250.0f,250.0f*h/w,1.0,-1.0);
else
glOrtho(-250.0f,250.0f*w/h,-250.0f,250.0f,1.0,-1.0);
}
//在窗口中绘制图形
voidReDraw(void)
{
//用当前背景色填充窗口
glClear(GL_COLOR_BUFFER_BIT);
//画出坐标线
DrawCordinateLine();
switch(m_DrawMode)
{
case1:
DDACreateLine(0,0,20,15,m_PointNumber);
break;
case2:
BresenhamLine(0,0,-20,15,m_PointNumber);
break;
case3:
Bresenham2Line(1,1,8,6,m_PointNumber);
break;
case4:
BresenhamCircle(0,0,20,m_PointNumber);
break;
case5:
Bresenham2Circle(10,8,m_PointNumber);
default:
break;
}
glFlush();
}
//设置时间回调函数
voidTimerFunc(intvalue)
{
if(m_PointNumber==0)
value=1;
m_PointNumber=value;
glutPostRedisplay();
glutTimerFunc(500,TimerFunc,value+1);
}
//设置键盘回调函数
voidKeyboard(unsignedcharkey,intx,inty)
{
if(key=='1')m_DrawMode=1;
if(key=='2')m_DrawMode=2;
if(key=='3')m_DrawMode=3;
if(key=='4')m_DrawMode=4;
if(key=='5')m_DrawMode=5;
m_PointNumber=0;
glutPostRedisplay();
}
//voidmain(void)
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
//初始化GLUT库OpenGL窗口的显示模式
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("基本图元绘制程序);
glutDisplayFunc(ReDraw);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(Keyboard);//键盘响应回调函数
glutTimerFunc(500,TimerFunc,1);
//窗口初始化
Initial();
glutMainLoop();//启动事件处理循环
return0;
}