回 帖 发 新 帖 刷新版面

主题:OPENGL球体自转公转问题(牛仔进)

好久没来,知道牛仔对OPENGL有研究,现在正在学,遇到个问题特来请教,欢迎会的朋友也回答下!
glPushMatrix();
 glRotatef((GLfloat)year,0.0,1.0,0.0);
 glTranslatef(3.0,0.0,0.0);
 glRotatef((GLfloat)day,0.0,1.0,0.0);
 glColor3f(0.0,1.0,0.0);
 glutWireSphere(0.3,10,8);
 glPushMatrix();
 glRotatef((GLfloat)year,0.0,1.0,0.0);
 glTranslatef(1.0,0.0,0.0);
 glRotatef((GLfloat)day,0.0,1.0,0.0);
 glColor3f(0.0,0.0,1.0);
 glutWireSphere(0.1,10,8);
 glPopMatrix();
 glPopMatrix();
以上代码是一个行星和它里面一个卫星,现在我想把它改为
 glPushMatrix();
 glRotatef((GLfloat)year,0.0,1.0,0.0);
 glTranslatef(3.0,0.0,0.0);
 glRotatef((GLfloat)day,1.0,1.0,4.0);//这行修改的
 glColor3f(0.0,1.0,0.0);
 glutWireSphere(0.3,10,8);
 glPushMatrix();
 glRotatef((GLfloat)year,0.0,1.0,0.0);
 glTranslatef(1.0,0.0,0.0);
 glRotatef((GLfloat)day,0.0,1.0,0.0);
 glColor3f(0.0,0.0,1.0);
 glutWireSphere(0.1,10,8);
 glPopMatrix();
 glPopMatrix();
这样可以实现行星自转倾斜而不是绕y轴,而卫星又能绕着行星转吗?(前面还有个主星体没把代码给出来!)

回复列表 (共3个回复)

沙发

我感觉最好是绘制一个物体之前PUSH一下,绘制完马上POP。不要PUSH,PUSH再POP,POP,容易乱。

板凳

主要是要理清,哪些变化是相互关联的,哪些变化是相互不会关联的。
就这个问题来说,卫星的状态与行星的位置有关,但与行星的自转无关。所以,绘制的步骤如下:
(1) 设置行星的位置
(2) glPushMatrix
(3) 设置行星的自转
(4) 绘制行星
(5) glPopMatrix
(6) 设置卫星的位置、旋转
(7) 绘制卫星
从上面的步骤可以看出,绘制卫星的时候,所使用的矩阵并不会受到行星自转的任何影响。

可以按照最“笨”的办法来思考。先把两个物体分别考虑,再把两者都需要计算的公共部分提取出来。
问:如何绘制行星?
答:计算行星位置、计算行星自转、绘制。
问:如何绘制卫星?
答:计算行星位置、计算卫星位置、计算卫星自转、绘制。
由于两者都需要计算行星位置,所以(提取公共部分)先计算行星位置,并保存(glPushMatrix),然后就可以反复利用这些公共信息,以便减少计算量。如果需要绘制的物体特别多,可以节省的计算量也是很可观的。

扩展:如果有或者更多的两个卫星,如何处理?
(1) 设置行星的位置
(2) glPushMatrix
(3) 设置行星的自转
(4) 绘制行星
(5) glPopMatrix
(6) glPushMatrix
(7) 设置一个卫星的位置、旋转
(8) 绘制这个卫星
(9) glPopMatrix
(10) 重复(6)-(9),直到所有卫星绘制完毕。

代码:(为了看得清楚些,我没有用球体,而改用立方体)
    float PI2 = 3.1415926f * 2.0f;
    float a1 = day / 360.0f * PI2;
    float a2 = day / 30.0f * PI2;

    glColor3f(1.0f, 0.0f, 0.0f);
    glutSolidCube(6960);

    glTranslatef(15000 * cos(a1), 15000 * sin(a1), 0.0f);

    glPushMatrix();
    glColor3f(0.0f, 0.0f, 1.0f);
    glRotatef(day, 4, 1, 0);
    glutSolidCube(1594.5);
    glPopMatrix();

    glColor3f(1.0f, 1.0f, 0.0f);
    glTranslatef(3800 * cos(a2), 3800 * sin(a2), 0.0f);
    // glRotateXX
    glutSolidCube(434.5);

3 楼

回答的相当详细,很满意!

我来回复

您尚未登录,请登录后再回复。点此登录或注册