中点画圆算法

如同光栅画线算法,每步都以间隔单位取样并确定离指定圆最近的像素位置。为了减少计算量,可以将圆八分,根据Bresenham画线算法。我们首先给出点位置函数:

   

即可得知:(1), 位于圆边界内;(2)位于圆边界上;(3), 位于圆边界外。

第一象限中,假设在绘制了像素点,下一步需要确定绘制的位置是,还是更接近圆。

则决策参数的圆函数方程在这两个像素的中点求值得到,

   

   

   

其中还是,取决于的符号。

算法过程:

1.输入圆半径和圆心,并得到圆周上的第一个点:

   

2.计算决策参数的初始值:

   

3.在每个位置,从开始,完成下列测试:假如,圆心在的圆的下一个点为,并且

   

否则,圆的下一个点是,并且

   

其中

4.确定在其他七个八分圆中的对称点。

5.将每个计算出的像素位置移动到圆心在的圆路径上,并画坐标值:

    

6.重复步骤3到步骤5,直至

 1 class ScreenPt {
 2 private:
 3     GLint x, y;
 4 
 5 public:
 6     ScreenPt() {
 7         x = y = 0;
 8     }
 9     void setCoords(GLint xCoordValue, GLint yCoordValue) {
10         x = xCoordValue;
11         y = yCoordValue;
12     }
13     GLint getx() const {
14         return x;
15     }
16     GLint gety() const {
17         return y;
18     }
19     void incrementx() {
20         ++x;
21     }
22     void decrementy() {
23         --y;
24     }
25 };
26 
27 void setPixel(GLint xCoord, GLint yCoord)
28 {
29     glBegin(GL_POINTS);
30     glVertex2i(xCoord, yCoord);
31     glEnd();
32 }
33 
34 void circlePlotPoints(GLint xc, GLint yc, ScreenPt circPt)
35 {
36     setPixel(xc + circPt.getx(), yc + circPt.gety());
37     setPixel(xc - circPt.getx(), yc + circPt.gety());
38     setPixel(xc + circPt.getx(), yc - circPt.gety());
39     setPixel(xc - circPt.getx(), yc - circPt.gety());
40     setPixel(xc + circPt.gety(), yc + circPt.getx());
41     setPixel(xc - circPt.gety(), yc + circPt.getx());
42     setPixel(xc + circPt.gety(), yc - circPt.getx());
43     setPixel(xc - circPt.gety(), yc - circPt.getx());
44 }
45 
46 void circleMidpoint(GLint xc, GLint yc, GLint radius)
47 {
48     ScreenPt circPt;
49 
50     GLint p = 1 - radius;   //Initial value for    midpoint parameter
51 
52     circPt.setCoords(0, radius);  //Set coords for top point of circle.
53     // Plot the initial point in each circle quadrant
54     circlePlotPoints(xc, yc, circPt);
55     // Calculate next point and polt in each octant
56     while (circPt.getx() < circPt.gety()) {
57         circPt.incrementx();
58         if (p < 0) {
59             p += 2 * circPt.getx() + 1;
60         }
61         else {
62             circPt.decrementy();
63             p += 2 * (circPt.getx() - circPt.gety()) + 1;
64         }
65         circlePlotPoints(xc, yc, circPt);
66     }
67 }

 

posted @ 2016-05-25 18:30  clairvoyant  阅读(4915)  评论(0编辑  收藏  举报