使用 OpenGL 中點圓算法繪製餅圖,展示數據分布比例。包含窗口初始化、圓繪製、扇區計算、比例縮放、窗口重繪等完整功能。
const GLdouble twoPi = 6.283185; // 2π
class scrPt { // 屏幕坐標點
public:
GLint x, y;
};
GLsizei winWidth = 400, winHeight = 300; // 窗口尺寸
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 pieChart(void) {
scrPt circCtr, piePt;
GLint radius = winWidth / 4; // 圓半徑
GLdouble sliceAngle, previousSliceAngle = 0.0;
GLint k, nSlices = 12; // 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.x = winWidth / 2;
circCtr.y = winHeight / 2;
// 繪製外圍圓(調用中點圓算法子程序)
circleMidpoint(circCtr, radius);
// 計算數據總和
for (k = 0; k < nSlices; k++) dataSum += dataValues[k];
// 繪製各扇區分隔線
for (k = 0; k < nSlices; k++) {
// 累積角度 = 2π * (數據值/總和) + 前累積角度
sliceAngle = twoPi * dataValues[k] / dataSum + previousSliceAngle;
// 扇區邊界點坐標
piePt.x = circCtr.x + radius * cos(sliceAngle);
piePt.y = circCtr.y + radius * sin(sliceAngle);
// 繪製從圓心到邊界的射線
glBegin(GL_LINES);
glVertex2i(circCtr.x, circCtr.y);
glVertex2i(piePt.x, piePt.y);
glEnd();
previousSliceAngle = sliceAngle;
}
}
void displayFcn(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0); // 藍色線條
pieChart();
glFlush();
}
void winReshapeFcn(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);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 300);
glutCreateWindow("Pie Chart");
init();
glutDisplayFunc(displayFcn);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();
return 0;
}

程序生成 12 扇區餅圖,每個扇區角度與數據值成正比,窗口縮放時自動適應。
glBegin(GL_TRIANGLE_FAN))glutBitmapCharacter)circleMidpoint