因为使用的是Qt框架,没有使用GLUT,所以改写了书中部分代码:
1. 文本用QString数组保存。
2. 绘制字符没有使用GLUT函数,直接使用QPainter进行绘制,Qt绘图坐标是以左上角为原点(0,0),因此,坐标也需要进行变换。
关键部分源代码,其它可以参照前面章节的例子。
a. 绘制折线图
QString label[12] = {
"Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
GLint dataValue[12] = {
420, 342, 324, 310, 262, 185, 190, 196, 217, 240, 312, 438
};
void OpenGLWidget::lineGraph()
{
GLint month, k;
GLint xRaster = 20;
GLint yRaster = 150;
GLint x = 30;
int h = this->height();
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for(k=0; k< 12; k++)
glVertex2i(x+k*50, dataValue[k]);
glEnd();
QPainter painter(this);
painter.setPen(Qt::red);
painter.setFont(QFont("Arial", 10));
for(k=0; k<12; k++) {
painter.drawText(x+k*50-5, h-dataValue[k]+10, "*");
}
painter.setPen(Qt::black);
painter.setFont(QFont("Helvecica", 12));
for(month=0; month<12; month++) {
for(k=3*month; k<3*month+3; k++)
painter.drawText(xRaster, h - yRaster, label[month]);
xRaster += 50;
}
glFlush();
}
效果图:
b. 绘制直方图
void OpenGLWidget::barChart()
{
GLint month, k;
GLint xRaster = 20;
GLint yRaster = 150;
int h = this->height();
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
for(k=0; k<12; k++)
glRecti(20+k*50, 165, 40+k*50, dataValue[k]);
QPainter painter(this);
painter.setPen(Qt::black);
painter.setFont(QFont("Helvecica", 12));
for(month=0; month<12; month++) {
for(k=3*month; k<3*month+3; k++)
painter.drawText(xRaster, h - yRaster, label[month]);
xRaster += 50;
}
}
效果图:
c. 绘制饼图
关于中点画圆的算法可以参考https://www.cnblogs.com/clairvoyant/p/5528067.html这篇文章,讲得还是比较清楚的。
GLsizei winWidth = 400, winHeight = 300;
const GLdouble twoPi = 6.283185;
void OpenGLWidget::pieChart()
{
QPoint circCtr, piePt;
GLint radius = winWidth / 4;
GLdouble sliceAngle, previousSliceAngle = 0.0;
GLint k, nSlices = 12;
GLfloat dataValues[12] = {
10.0, 7.0, 13.0, 5.0, 13.0, 14.0, 3.0, 16.0, 5.0, 3.0, 17.0, 8.0
};
GLfloat dataSum = 0.0;
circCtr.setX(winWidth / 2);
circCtr.setY(winHeight / 2);
circleMidpoint(circCtr, radius);
for(k=0; k
效果图: