You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在传统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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:24:57