如何在传统OpenGL中绘制绕自身枢轴旋转的太阳
解决太阳固定位置自转的问题
问题原因
当前代码中,glRotatef 默认绕世界坐标系原点(0,0)旋转,而你绘制的太阳中心在(450,450),导致太阳整体绕原点做圆周运动。要实现自转,需将旋转枢轴切换到太阳自身的中心,这需要调整OpenGL矩阵变换的顺序(OpenGL矩阵变换是逆序执行的)。
修改后的完整代码
#include <windows.h> // for MS Windows #include <GL/glut.h> // GLUT, include glu.h and gl.h #include <math.h> float sunAngle = 0.0f; // Angle for sun rotation // 绘制椭圆(原circle函数实际是椭圆,rx/x半径,ry/y半径,cx/cy中心坐标) void circle(GLfloat rx, GLfloat ry, GLfloat cx, GLfloat cy) { glBegin(GL_POLYGON); glVertex2f(cx, cy); for (int i = 0; i <= 360; i++) { float angle = i * 3.1416 / 180; float x = rx * cos(angle); float y = ry * sin(angle); glVertex2f((x + cx), (y + cy)); } glEnd(); } // 绘制太阳:调整矩阵变换顺序实现自转 void sun() { glPushMatrix(); // 1. 将坐标系平移到太阳的中心位置(450,450) glTranslatef(450.0, 450.0, 0.0); // 2. 绕当前坐标系原点(即太阳中心)旋转 glRotatef(sunAngle, 0.0, 0.0, 1.0); // 3. 以当前坐标系原点为中心绘制太阳 glColor3f(1.0f, 1.0f, 0.0f); // 黄色 circle(20, 30, 0.0, 0.0); glPopMatrix(); } void update(int value) { // 更新太阳旋转角度 sunAngle += 1.0f; if (sunAngle > 360) { sunAngle -= 360; } glutTimerFunc(20, update, 0); } // 补充原代码缺失的init函数 void init() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 900.0, 0.0, 500.0); // 匹配窗口尺寸的正交投影 } void display (void){ glClear(GL_COLOR_BUFFER_BIT); // 绘制天空背景 glColor3ub(30, 144, 255); glBegin(GL_POLYGON); glVertex2d(0, 0); glVertex2d(900, 0); glVertex2d(900, 500); glVertex2d(0, 500); glEnd(); sun(); glFlush(); glutSwapBuffers(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 改用双缓冲避免闪烁 glutInitWindowSize(900, 500); glutInitWindowPosition(100, 100); glutCreateWindow("Sun"); init(); glutDisplayFunc(display); glutTimerFunc(16, update, 0); glutMainLoop(); return 0; }
关键修改点
- 矩阵变换顺序调整:先执行
glTranslatef(450,450,0)将坐标系移到太阳中心,再执行glRotatef,此时旋转的枢轴就是太阳自身中心,最后绘制以(0,0)为中心的太阳。 - 补充缺失的
init函数:原代码未定义init函数,编译会报错,这里添加了正交投影设置,确保坐标系与窗口尺寸匹配。 - 优化显示模式:将
GLUT_SINGLE改为GLUT_DOUBLE,配合glutSwapBuffers减少动画闪烁。 - 修正天空绘制范围:原天空只画了500x500区域,改为匹配窗口的900x500,避免右侧空白。
内容的提问来源于stack exchange,提问作者I Can Done
相关产品推荐
相关产品推荐

