Advertisement

Qt5.12+OpenGL 计算机图形学(第四版)第4章例子 输出图元

阅读量:

因为使用的是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();
    
 }
    
  
    
    
    
    
    AI写代码cpp
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-05-31/81dibzRSExk9P5FGWLntV7fpv3qZ.png)

效果图:

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;
    
     }
    
 }
    
    
    
    
    AI写代码cpp
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-05-31/c9upgWDYZ6ONr31Pl8jS2kU4XLJA.png)

效果图:

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<nSlices; k++) {
    
     dataSum += dataValues[k];
    
     }
    
  
    
     for(k=0; k<nSlices; k++) {
    
     sliceAngle = twoPi * dataValues[k] / dataSum + previousSliceAngle;
    
     piePt.setX(circCtr.x() + radius * cos(sliceAngle));
    
     piePt.setY(circCtr.y() + radius * sin(sliceAngle));
    
  
    
     glBegin(GL_LINES);
    
         glVertex2i(circCtr.x(), circCtr.y());
    
         glVertex2i(piePt.x(), piePt.y());
    
     glEnd();
    
     previousSliceAngle = sliceAngle;
    
     }
    
 }
    
  
    
 void putpixel(int x0, int y0, int x, int y)
    
 {
    
     glBegin(GL_POINTS);
    
     glVertex2f(x0 + x, y0 + y);
    
     glVertex2f(x0 + x, y0 - y);
    
     glVertex2f(x0 - x, y0 + y);
    
     glVertex2f(x0 - x, y0 - y);
    
     glVertex2f(x0 + y, y0 + x);
    
     glVertex2f(x0 + y, y0 - x);
    
     glVertex2f(x0 - y, y0 + x);
    
     glVertex2f(x0 - y, y0 - x);
    
     glEnd();
    
 }
    
  
    
 /* * 通过中点和半径画圆
    
  */
    
 void OpenGLWidget::circleMidpoint(QPoint c, int r)
    
 {
    
     int x, y, p;
    
     x = 0; y = r; p = 1 - r;
    
     while(x <= y) {
    
     putpixel(c.x(), c.y(), x, y);
    
     if ( p < 0 ) {
    
         p += 2 * x + 1;
    
     } else {
    
         p += 2 * (x - y) + 1;
    
         y--;
    
     }
    
     x++;
    
     }
    
 }
    
    
    
    
    AI写代码cpp
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-05-31/t2dSjhQ8bMLn6sEYRAVGp7g9Uk5T.png)

效果图:

全部评论 (0)

还没有任何评论哟~