计算机图形学第四章后边示例代码里有一段画饼图的练习,画出来是这样的
中间有一段中心画圆法未实现,搜集了网上资料补全并执行了这段代码,作为openGL的学习练习
#include <GL/glut.h> #include <stdlib.h> #include <math.h> GLsizei winWidth = 400, winHeight = 300; const GLdouble twoPi = 6.283185; class scrPt { public: GLint x, y; }; class screenPt { public: screenPt() { x = y = 0; } GLint x, y; void setCoords(GLint xCoordValue, GLint yCorrdValue) { x = xCoordValue; y = yCorrdValue; } GLint getx() const { return x; } GLint gety() const { return y; } void incrementx() { x++; } void decrementy() { y--; } }; void init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); // 将窗口北京初始化为白色 glMatrixMode(GL_PROJECTION); // 对投影矩阵操作 gluOrtho2D(0.0, 200.0, 0.0, 150.0); // 建立一个2D坐标系 } void setPixel(GLint xCoord, GLint yCoord) { 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(scrPt circCtr, GLint radius){ screenPt circPt; GLint p = 1 - radius; circPt.setCoords(0, radius); circlePlotPoints(circCtr.x, circCtr.y, circPt); while (circPt.getx() < circPt.gety()){ circPt.incrementx(); if (p < 0) p += 2 * circPt.getx() + 1; else{ circPt.decrementy(); p += 2 * (circPt.getx() - circPt.gety()) + 1; } circlePlotPoints(circCtr.x, circCtr.y, circPt); } } template<class T> int length(T& arr) { return sizeof(arr) / sizeof(arr[0]); } // 画饼图 void pieChart(void) { scrPt circCtr, piePt; GLint radius = winHeight / 4; // 圆的半径 GLdouble sliceAngle, previousSliceAngle = 0.0; 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.x = winWidth / 2; circCtr.y = winHeight / 2; circleMidpoint(circCtr, radius); //中心画圆法,画出饼图外圆 for(GLint k = 0; k < length(dataValues); k++) { dataSum += dataValues[k]; // 计算数据总量 } for(GLint k = 0; k < length(dataValues); k++) { sliceAngle = twoPi * dataValues[k] / dataSum + previousSliceAngle; // 计算角度 piePt.x = circCtr.x + radius * cos(sliceAngle); // 计算落点x piePt.y = circCtr.y + radius * sin(sliceAngle); // 计算落点y glBegin(GL_LINES); // 划线从原点到数据落点的 glVertex2i(circCtr.x, circCtr.y); glVertex2i(piePt.x, piePt.y); glEnd(); previousSliceAngle = sliceAngle; } } void displayFunc(void) { glClear(GL_COLOR_BUFFER_BIT); //显示缓存背景色 glColor3f(1.0, 0.0, 1.0); // 初始化画笔颜色 pieChart(); glFlush(); } void winReshapeFunc(GLint newWidth, GLint newHeight) { glMatrixMode(GL_PROJECTION); // 对投影矩阵操作 glLoadIdentity(); // 重置当前指定的矩阵为单位矩阵 gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight)); // 重新建立坐标系 glClear(GL_COLOR_BUFFER_BIT); winWidth = newWidth; winHeight = newHeight; } int main(int argc, char ** argv) { glutInit(&argc, argv); // 初始化 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // 单一缓存RGB模式 glutInitWindowPosition(100, 100); // 初始化窗口位置 glutInitWindowSize(winWidth, winHeight); // 初始化窗口大小 glutCreateWindow("en?~"); // 创建窗口 init(); glutDisplayFunc(displayFunc); // 注册显示回调函数 glutReshapeFunc(winReshapeFunc); // 改变窗口大小回调函数 glutMainLoop(); return 0; }
原文地址:https://www.cnblogs.com/ziyoulu/p/10040950.html
时间: 2024-11-05 22:44:03