折线图
大家都知道MATLAB中画这种类型的统计图非常的简单,在OpenGL中画这种图也不是特别难的事情
现在先看如何画折线图
#include <gl/glut.h>
GLsizei winWidth = 600, winHeight = 500;
GLint xRaster = 25,yRaster = 150;
GLubyte label[36] = {'J','a','n','F','e','b','M','a','r','A','p','r','M','a','y','J','u','n',
'j','u','l','A','u','g','S','e','p','O','c','t','N','o','v','D','e','c'};
GLint datevalue[12] = {420,342,324,310,262,185,190,196,217,240,312,469};
void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
void display()
{
GLint month,k;
GLint x = 30;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);//坐标轴
glVertex2i(0,winHeight/2);
glVertex2i(winWidth,winHeight/2);
glVertex2i(winWidth/2,0);
glVertex2i(winWidth/2,winHeight);
glEnd();
glColor3f(0.0,0.0,1.0);//趋势折线
glBegin(GL_LINE_STRIP);
for(k = 0;k<12;k++)
glVertex2i(x+k*50,datevalue[k]);
glEnd();
glColor3f(0.0,1.0,0.0);
for (k=0;k<12;k++)
{
glRasterPos2i(xRaster+k*50,datevalue[k]-4);
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,'*');
}
glColor3f(1.0,0.0,1.0);
xRaster = 20;
for (month = 0;month<12;month++)
{
glRasterPos2i(xRaster,yRaster);
for (k =month*3;k<month*3+3;k++ )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,label[k]);
}
xRaster += 50;
}
glFlush();
}
void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(200,200);
glutInitWindowSize(winWidth,winHeight);
glutCreateWindow("hello");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
这个程序有一个问题,我不知道为什么会出现,就是当你把窗口的大小改变的时候,标记的星号就会偏跑,有谁了解可以告知,谢谢!!
柱状图
现在看如何画柱状图,道理和上面这个程序是一样的
#include <gl/glut.h>
GLsizei winWidth = 600, winHeight = 500;
GLint xRaster = 25,yRaster = 150;
GLubyte label[36] = {'J','a','n','F','e','b','M','a','r','A','p','r','M','a','y','J','u','n',
'j','u','l','A','u','g','S','e','p','O','c','t','N','o','v','D','e','c'};
GLint datevalue[12] = {420,342,324,310,262,185,190,196,217,240,312,469};
void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,winWidth,0.0,winHeight);
}
void display()
{
GLint month,k;
GLint x = 30;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);//坐标轴
glVertex2i(0,winHeight/2);
glVertex2i(winWidth,winHeight/2);
glVertex2i(winWidth/2,0);
glVertex2i(winWidth/2,winHeight);
glEnd();
glColor3f(0.0,1.0,0.0);
for (k=0;k<12;k++)
{
glRecti(20+k*50,165,40+k*50,datevalue[k]);
}
glColor3f(1.0,0.0,1.0);
xRaster = 20;
for (month = 0;month<12;month++)
{
glRasterPos2i(xRaster,yRaster);
for (k =month*3;k<month*3+3;k++ )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,label[k]);
}
xRaster += 50;
}
glFlush();
}
void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(200,200);
glutInitWindowSize(winWidth,winHeight);
glutCreateWindow("hello");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
截图如下:
饼状图
饼状图的生成需要通过之前的画圆环的程序
整个程序的思路就是画出一个圆,然后计算参数的比例,将比例换成角度的比值,通过比值画直线,这样就把圆形分割出来了,但是我想为每个部分添加一个颜色,这样比较区分,但是我发现比较困难,不知道大家有没有什么办法,本人菜鸟,谢谢!!
#include <gl/glut.h>
#include <stdlib.h>
#include <math.h>
GLsizei winWidth = 400;
GLsizei winHeight = 400;
const GLdouble twopi = 6.28f;
class screenpt
{
public:
GLint x,y;
public:
screenpt()
{
x = y = 0;
}
void setcoords(GLint xcoord,GLint ycoords)
{
x = xcoord;
y = ycoords;
}
GLint getx() const
{
return x;
}
GLint gety() const
{
return y;
}
void incrementx()
{
x++;
}
void incrementy()
{
y++;
}
void decrementx()
{
x--;
}
void decreamenty()
{
y--;
}
};
void setpixel(GLint xcoord,GLint ycoord)
{
//glPointSize(5);
glBegin(GL_POINTS);
glVertex2i(xcoord,ycoord);
glEnd();
}
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 circleMIDpoint(GLint xc,GLint yc,GLint radius)
{
screenpt cirpt;
GLint p =1-radius;
cirpt.setcoords(0,radius);
circlePlotPoints(xc,yc,cirpt);
while(cirpt.getx()<cirpt.gety())
{
cirpt.incrementx();
if(p<0)
{
p += 2*cirpt.getx() + 1;
}
else
{
cirpt.decreamenty();
p += 2*(cirpt.getx()-cirpt.gety()) + 1;
}
circlePlotPoints(xc,yc,cirpt);
}
}
void inti()
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,200,0.0,200);
}
void pieChart()
{
screenpt circCtr,pirPt;
GLint radius = winWidth/4;
GLdouble sliceAngle,previousSliceAngle = 0.0;
GLint dataSum = 0;
float color = 0.0;
GLint k,nSlices = 12;
GLint datevalue[12] = {420,342,324,310,262,185,190,196,217,240,312,469};
circCtr.x = winWidth/2;
circCtr.y = winHeight/2;
circleMIDpoint(circCtr.x,circCtr.y,radius);
for (k=0;k<nSlices;k++)
{
dataSum += datevalue[k];
}
for (k=0;k<nSlices;k++)
{
sliceAngle = twopi * datevalue[k]/dataSum + previousSliceAngle;
pirPt.x = circCtr.x + radius * cos(sliceAngle);
pirPt.y = circCtr.y + radius * sin(sliceAngle);
glBegin(GL_LINES);
//glColor3f(color++/(float)nSlices,0.0,1.0);//修改线的颜色
glVertex2i(circCtr.x,circCtr.y);
glVertex2i(pirPt.x,pirPt.y);
glEnd();
previousSliceAngle = sliceAngle;
}
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
pieChart();
glFlush();
}
void reshape(int w,int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,(GLdouble)w,0.0,(GLdouble)h);
glClear(GL_COLOR_BUFFER_BIT);
winWidth = w;
winHeight = h;
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("hello");
inti();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}