母婴网站建设初衷/app推广团队
圆方程为非线性的,计算像素与圆的距离必须进行平方运算,Bresenham画圆方法则通过比较像素与圆的距离的方法而避免了平方根运算。
然而,不做平方运算而直接比较距离是可能得。该方法的基本思想是检验两像素间的中间位置以确定该中点是在圆边界值内还是之外。
【注】算法代码如下,其中void
circleBresham(GLint xc,GLint yc,GLint radius)为用Bresenham算法画圆的算法,而其中void circleMidpoint(GLint xc,GLint yc,GLint
radius)为中点画圆的算法:
#include
#include
#ifdef __APPLE__
#include
#else
#include
#endif
#include
void init (void)
{
glClearColor(0.0, 1.0, 0.0, 0.0); // Set display-window
color to white.
glMatrixMode (GL_PROJECTION);
// Set projection parameters.
gluOrtho2D (0.0, 200.0, 0.0, 150.0);
}
class screenPt
{
private:
GLint x,y;
public:
screenPt(){
x = y =0;
}
void setCoords(GLint xCoordValue,GLint yCoordValue){
x = xCoordValue;
y = yCoordValue;
}
GLint getx() const
{
return x;
}
GLint gety() const
{
return y;
}
void incrementx()
{
x ++;
}
void decrementy()
{
y--;
}
};
void setPixel(GLint xCoord,GLint
yCoord)
{
glBegin(GL_POINTS);
glVertex2i(xCoord,yCoord);
glEnd();
//glFlush();
}
void circleMidpoint(GLint
xc,GLint yc,GLint radius)
{
glColor
3f(1.0,0.0,0.0);
screenPt circPt;
GLint p = 1 - radius;
circPt.setCoords(0,radius);
void circlePlotPoints(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);
}
}
void circleBresham(GLint
xc,GLint yc,GLint radius)
{
glColor3f(1.0,0.0,0.0);
screenPt circPt;
//GLint p = 1 - radius;
circPt.setCoords(0,radius);
void circlePlotPoints(GLint,GLint,screenPt);
circlePlotPoints(xc,yc,circPt);
while(circPt.getx()< circPt.gety())
{
GLint x1,x2,y1,y2;
circPt.incrementx();
x1 = circPt.getx();
y1 = circPt.gety();
x2 = circPt.getx();
y2 = circPt.gety()-1;
//if
((x1*x1+y1*y1-radius*radius)
//}
if
(fabs(x1*x1+y1*y1-radius*radius)>fabs(x2*x2+y2*y2-radius*radius)){
circPt.decrementy();
// p += 2*(circPt.getx() - circPt.gety()) + 1;
}
circlePlotPoints(xc,yc,circPt);
}
}
void circlePlotPoints(GLint xc,GLint yc,screenPt
circPt)
{
setPixel(xc + circPt.getx(),yc + circPt.gety());
setPixel(xc - circPt.getx(),yc + circPt.gety());
setPixel(xc + circPt.getx(),yc - circPt.gety());
setPixel(xc - circPt.getx(),yc - circPt.gety());
setPixel(xc + circPt.gety(),yc + circPt.getx());
setPixel(xc - circPt.gety(),yc + circPt.getx());
setPixel(xc + circPt.gety(),yc - circPt.getx());
setPixel(xc - circPt.gety(),yc - circPt.getx());
}
void pointsFun(void)
{
glPointSize(3.0);
glEnable(GL_POINT_SMOOTH);
glClear(GL_COLOR_BUFFER_BIT);
circleBresham(100,100,30);
glFlush();
}
int main (int argc, char** argv)
{
glutInit (&argc, argv);
// Initialize GLUT.
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); //
Set display mode.
glutInitWindowPosition (50, 100); //
Set top-left display-window position.
glutInitWindowSize (400, 300);
// Set display-window width and height.
glutCreateWindow ("An Example OpenGL Program"); // Create display
window.
init();
// Execute initialization procedure.
glutDisplayFunc (pointsFun);
// Send graphics to display window.
glutMainLoop ( );// Send graphics to display window.
// Display everything and wait.
return 0;
}