使用OpenGL Midpoint Circle 算法来绘制一个八卦图

Midpoint Circle 算法 是计算机图形学中画圆的一种重要的算法,用这种算法我们可以很轻易的绘制出一个圆形的图案,在这里我将使用OpenGL来绘制一个八卦图,也主要就是使用Midpoint Circle 算法进行圆以及半圆等的绘制然后填充。

主要的思路如下:

   首先我们使用Midpoint Circle 算法来绘制一个圆形,然后对于圆形的上半部分使用黑色进行填充,然后再黑色调冲部分的左半圆部分使用大圆半径的一半大小来绘制一个白色填充部分,然后在下半圆的右半部分使用同样的方法来填充一块黑色的部分,然后再对两个部分进行白色填充黑色的实心圆,黑色部分填充白色的实心圆,这样一个八卦图就基本成形了。当然这里只是我个人的一点愚见,大家有什么更好的画法希望能够进行讨论,我之所以贴出来也就是为了和大家一起讨论学习。。哈哈

Midpoint Circle 算法概述:

设圆之半径为r。先考虑圆心在(0,0),并从x=0, y=r开始的顺时针方向的1/8圆周的生成过程。在这种情况下,x每步增加1,从x=0开始,到x=y结束。即有:xi+1=xi+1相应的yi+1则在两种可能中选择:yi+1=yi,或者yi+1=yi-1选择的原则是考察精确值y靠近yi还是靠近yi-1
 
因此定义Pk如下:
由此先画 1/8 个圆 , 再画其余对称的 7 1/8 个圆 ( 坐标变换得来 )

画圆的OpenGL代码如下:

   

  /*工程名称:  八卦图
   *版权信息:  CopyRight By Fonhal
   *作者信息:  :fonhal
   *工程描述: 使用OpenGL绘制一个八卦图
*/


//  八卦图.cpp : 定义控制台应用程序的入口点。
//

#include 
" stdafx.h "
#include 
< glglut.h >


void  init( void )
{
    glClearColor(
1.0,1.0,1.0,0.0);    //设置窗口背景色
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(
0.0,400.0,0.0,400.0);    //窗口坐标左下角(0,0), 右上角(400,400)
}

// 功能说明: 画一个圆的边缘,用GL_LINES去填充外面的线
void  DrawCircle( int  PX,  int  PY,  int  Radius)
{
    
int px=0, py=0;
    
int pX=0, pY=Radius;
    
int pkNow=5/4-Radius, pkNext=0;
    glColor3f(
0.0,0.0,0.0);
    
while(px<=py)
    
{
        px
=pX;py=pY;
        
if(pkNow<0)
        
{
            pkNext
=pkNow+2*px+3;
            pkNow
=pkNext;
            pX
=px+1;
        }
    
        
else
        
{
            pkNext
=pkNow+2*px-2*py+5;
            pkNow
=pkNext;
            pX
=px+1;
            pY
=py-1;
        }

        glBegin(GL_LINES);
            
//第一象限
            glVertex2i(PX+px,PY+py);
            glVertex2i(PX
+pX,PY+pY);
            glVertex2i(PX
+py,PY+px);
            glVertex2i(PX
+pY,PY+pX);
            
//第二象限
            glVertex2i(PX-px,PY+py);
            glVertex2i(PX
-pX,PY+pY);
            glVertex2i(PX
-py,PY+px);
            glVertex2i(PX
-pY,PY+pX);
            
//第三象限
            glVertex2i(PX-py,PY-px);
            glVertex2i(PX
-pY,PY-pX);
            glVertex2i(PX
-px,PY-py);
            glVertex2i(PX
-pX,PY-pY);
            
//第四象限
            glVertex2i(PX+py,PY-px);
            glVertex2i(PX
+pY,PY-pX);
            glVertex2i(PX
+px,PY-py);
            glVertex2i(PX
+pX,PY-pY);
        glEnd();
    }

    glFlush();
}

// 功能说明: 画一个实心圆,可以自定义填充颜色,并且可以通过选择Pozition来选择位置,如果Pozition=1则画一个完整的实心圆,Pozition=2画一个上半圆,Pozition=3画一个下半圆
void  DrawCircle( int  PX,  int  PY,  int  Radius,  int  red,  int  green,  int  blue, int  pozition)
{
    
int px=0, py=0;
    
int pX=0, pY=Radius;
    
int pkNow=5/4-Radius, pkNext=0;
    glColor3f(red,green,blue);
    
while(px<=py)
    
{
        px
=pX;py=pY;
        
if(pkNext<0)
        
{
            pkNext
=pkNow+2*px+3;
            pkNow
=pkNext;
            pX
=px+1;
        }
    
        
else
        
{
            pkNext
=pkNow+2*px-2*py+5;
            pkNow
=pkNext;
            pX
=px+1;
            pY
=py-1;
        }

        
if(1==pozition)//当pozition=1的时候绘制一个完整的实心圆,使用凸三角形进行填充
        {
        
//第一象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
+px,PY+py);
            glVertex2i(PX
+pX,PY+pY);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
+py,PY+px);
            glVertex2i(PX
+pY,PY+pX);
            glVertex2i(PX,PY);
         glEnd();
        
//第二象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
-px,PY+py);
            glVertex2i(PX
-pX,PY+pY);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
-py,PY+px);
            glVertex2i(PX
-pY,PY+pX);
            glVertex2i(PX,PY);
         glEnd();
        
//第三象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
-py,PY-px);
            glVertex2i(PX
-pY,PY-pX);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
-px,PY-py);
            glVertex2i(PX
-pX,PY-pY);
            glVertex2i(PX,PY);
         glEnd();
        
//第四象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
+py,PY-px);
            glVertex2i(PX
+pY,PY-pX);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
+px,PY-py);
            glVertex2i(PX
+pX,PY-pY);
            glVertex2i(PX,PY);
         glEnd();
        }

        
else if(2==pozition)//当pozition=2的时候绘制上半圆,使用凸三角形进行填充
        {
        
//第一象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
+px,PY+py);
            glVertex2i(PX
+pX,PY+pY);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
+py,PY+px);
            glVertex2i(PX
+pY,PY+pX);
            glVertex2i(PX,PY);
         glEnd();
        
//第二象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
-px,PY+py);
            glVertex2i(PX
-pX,PY+pY);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
-py,PY+px);
            glVertex2i(PX
-pY,PY+pX);
            glVertex2i(PX,PY);
         glEnd();
        }

        
else if(3==pozition)//当pozition=3的时候绘制下半圆,使用凸三角形进行填充
        {
        
//第三象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
-py,PY-px);
            glVertex2i(PX
-pY,PY-pX);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
-px,PY-py);
            glVertex2i(PX
-pX,PY-pY);
            glVertex2i(PX,PY);
         glEnd();
        
//第四象限
        glBegin(GL_POLYGON);
            glVertex2i(PX
+py,PY-px);
            glVertex2i(PX
+pY,PY-pX);
            glVertex2i(PX,PY);
         glEnd();
        glBegin(GL_POLYGON);
            glVertex2i(PX
+px,PY-py);
            glVertex2i(PX
+pX,PY-pY);
            glVertex2i(PX,PY);
         glEnd();
        }

    }

    glFlush();
}

// 功能说明: 调用上面的函数来画一个八卦图形
void  DisplayFunc()
{
    glClear(GL_COLOR_BUFFER_BIT);
    DrawCircle(
200,200,144);//画一个圆心在(200,200)半径为144的圆
    DrawCircle(200,200,144,0,0,0,2);//画一个圆心在(200,200)半径为144填充颜色为白色的上半圆
    DrawCircle(129,200,72,1,1,1,2);//画一个圆心在(129,200)半径为72填充颜色为白色的上半圆
    DrawCircle(272,200,72,0,0,0,3);//画一个圆心在(272,200)半径为72填充颜色为黑色的下半圆
    DrawCircle(129,200,7);//画一个圆心在(129,200)半径为7黑色圆
    DrawCircle(129,200,8,0,0,0,1);//画一个圆心在(129,200)半径为8填充颜色为黑色的实心圆
    DrawCircle(272,200,7);//画一个圆心在(272,200)半径为7黑色圆
    DrawCircle(272,200,8,1,1,1,1);//画一个圆心在(272,200)半径为8填充颜色为白色的实心圆
}


void  main( int  argc,  char   ** argv)
{
    glutInit(
&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE
|GLUT_RGB);    //单缓存+RGB方式
    glutInitWindowPosition(50,100);    //窗口位置
    glutInitWindowSize(400,400);    //窗口大小
    glutCreateWindow("八卦");    //建立窗口

    init();
    glutDisplayFunc(DisplayFunc);    
//显示图形
    glutMainLoop();    //等待
}

 

绘制结果如下:

  效果图

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值