使用OpenGL Midpoint Circle 算法来绘制一个八卦图
2007-10-14 10:22
896 查看
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(); //等待
}
绘制结果如下:
主要的思路如下:
首先我们使用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(); //等待
}
绘制结果如下:
相关文章推荐
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——3.2 使用OpenGL ES 2.0绘制一个球
- opengl es3.0学习篇七:使用opengl绘制一个立方体
- 在VC中,使用OpenGL绘制一个矩形、三角形、三个点和三条直线,由直线组成新的三角形
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- 使用OPENGL绘制一个带轨迹的小球
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形 【转】
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- 使用OpenGL绘制一个矩形,并在窗口大小改变时保持它的形状
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- 使用opengl绘制一个立方体
- 【OpenGL4.0】GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
- IOS 中openGL使用教程2(openGL ES 入门篇 | 绘制一个多边形)
- 使用OPENGL绘制一个带轨迹的小球
- 创建一个大小为400*400的三通道的RGB图像。将它的全部元素置0.使用指针算法将以(100,100)与(300,300)为项点绘制一个绿色的矩形。
- 【算法之链表(三)】单链表中,在仅允许使用一个指针的情况下,在指定的节点前面插入以及删除一个节点
- OpenGL:绘制一个旋转的正方形
- 每天一个OpenGL程序 第六篇 图形的组合绘制