今天一时高兴,改进了以前在OpenGL中做的一个360度画圆的函数,完成个Bresenham圆弧画法,发在此处,供各位参考。
这个是用的OpenGL控制台形式,采用了那个半官方库glut。
//cnsGLArc.cpp : Defines the entry point for the console application.
//Filename:cnsGLArc.cpp
//Function:Draw arc by Bresenham
//Author:9Cat
//OS:WindowsXP Sp2
//Development Tool:Visual C++ 2005
//Other refrence:OpenGL
//First Create Time:2008-07-13 18:37
//Last Modify Time:2008-07-13 22:38
#pragma once
#pragma comment(linker,"/subsystem:/"windows/" /entry:/"mainCRTStartup/"")
#define WIN32_LEAN_AND_MEAN
#include<tchar.h>
#include<stdlib.h>
#include<windows.h>
#include<gl/glut.h>
#include<cmath>
#include<iostream>
using namespace std;
const int iXSTART=200;
const int iYSTART=100;
const int iWIDTH=500;
const int iHEIGHT=400;
const float fORG=0.0f;
const float fTX=0.8f;
const float fTY=0.7f;
const float fR=0.4f;
const float fDIFFER=0.001f;
//点结构体定义
struct mypoint
{
float x;
float y;
};
//点坐标的xy坐标赋值与初始化函数
void proInitp(struct mypoint *,float,float);
//单位升降级函数
float flaUpUnit(float,int);
float flaDownUnit(float,int);
//直线测试函数的声明
void proLine(struct mypoint *,struct mypoint *);
//画点函数的声明
void proPoint(struct mypoint *);
//Bresenham画圆算法的声明
void proBresenArc(struct mypoint *,float);
//主渲染函数实现
void renderscene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
//主要绘图操作在该部分实现
//绘制直线
struct mypoint stuA,stuB,*stpA,*stpB;;
stpA=&stuA;
stpB=&stuB;
proInitp(stpA,fORG,fORG);
proInitp(stpB,fTX,fTY);
proLine(stpA,stpB);
//绘制圆弧
struct mypoint stuCent,*stpCent;
stpCent=&stuCent;
proInitp(stpCent,fORG,fORG);
proBresenArc(stpCent,fR);
//glutSwapBuffers();
}
//环境设置函数实现
void setuprc(void)
{
glClearColor(0.0f, 0.0f, 0.0f,0.1f);
}
//程序主函数
int main()
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
//双缓冲模式需配合renderscene中的glutSwapBuffers使用
//glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutCreateWindow("Draw arc by bresenham");
glutPositionWindow(iXSTART,iYSTART);
glutReshapeWindow(iWIDTH,iHEIGHT);
glutDisplayFunc(renderscene);
setuprc();
glutMainLoop();
return 0;
}
//*************各函数定义过程**************
//初始化点结构的横纵坐标
void proInitp(struct mypoint *myp,float x,float y)
{
myp->x=x;
myp->y=y;
}
//单位变换函数的实现
float flaUpUnit(float flaVar,int intTimes)
{
flaVar=flaVar*intTimes;
return flaVar;
}
float flaDownUnit(float flaVar,int intTimes)
{
flaVar=flaVar/intTimes;
return flaVar;
}
//直线测试函数的实现
void proLine(struct mypoint *stpStart,struct mypoint *stpEnd)
{
glBegin(GL_LINES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(stpStart->x,stpStart->y);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex2f(stpEnd->x,stpEnd->y);
glEnd();
glFlush();
}
//画点函数的实现
void proPoint(struct mypoint *stpPoint)
{
glBegin(GL_POINTS);
glColor3f(1.0f,1.0f,1.0f);
glVertex2f(stpPoint->x,stpPoint->y);
glEnd();
glFlush();
}
//Bresenham画圆算法的实现
void proBresenArc(struct mypoint *stpCenter,float flaR)
{
float flaX,flaY,flaDis;
struct mypoint stuPB,*stpPB;
stpPB=&stuPB;
flaX=0.0f;
flaY=flaR;
flaX=flaUpUnit(flaX,iWIDTH/2);
flaY=flaUpUnit(flaY,iHEIGHT/2);
flaR=flaUpUnit(flaR,iWIDTH/2);
stpCenter->x=flaUpUnit(stpCenter->x,iWIDTH/2);
stpCenter->y=flaUpUnit(stpCenter->y,iHEIGHT/2);
flaDis=3-2*flaR;
while(flaX<flaY)
{
stpPB->x=(flaX+stpCenter->x);
stpPB->y=(flaY+stpCenter->y);
stpPB->x=flaDownUnit(stpPB->x,iWIDTH/2);
stpPB->y=flaDownUnit(stpPB->y,iHEIGHT/2);
proPoint(stpPB);
if(flaDis<0)
{
flaDis=flaDis+4*flaX+6;
}
else
{
flaDis=flaDis+4*(flaX-flaY)+10;
flaY=flaY-1;
}
flaX=flaX+1;
}
if((flaX-flaY)<=fDIFFER)
{
stpPB->x=(flaX+stpCenter->x);
stpPB->y=(flaY+stpCenter->y);
stpPB->x=flaDownUnit(stpPB->x,iWIDTH/2);
stpPB->y=flaDownUnit(stpPB->y,iHEIGHT/2);
proPoint(stpPB);
}
}