JOGL太阳系模型相机环绕行星时无法稳定对准中心问题
问题描述
我在JOGL太阳系模型中尝试让相机环绕行星运动,但行星无法保持在视野中心。相机应沿固定半径的完美圆周环绕行星,行星需始终出现在屏幕中心,但实际并非如此。我曾尝试排查行星计算位置与实际位置的偏差,或调整三角函数,但结果反而让相机和行星的状态更混乱。
编辑更新
我改用gluLookAt函数,并确保函数调用顺序如下:
- 投影矩阵(
gluPerspective,未包含在更新内容中) - 模型视图矩阵(
gluLookAt) - 变换操作(
rotate、translate) - 绘制行星(
gluSphere)
但相机仍沿错误路径运动,仿佛处于原点附近。我看到的画面似乎是从太阳内部、背向原点的视角观察太阳系模型。
核心代码
display函数
public void display(GLAutoDrawable drawable) { gl = initMatrix(drawable, GL2.GL_MODELVIEW); // Calculates the orbital and rotational angles of each planet for(Planet art : artbook) { orbitPlanet(art); art.rotate(frameCount); } //The planet the camera is tracking is Earth Planet earth = artbook.get(3); float planetX = earth.getX(), planetZ = earth.getZ(), rotation = earth.getRotation(), camOffset = 0.1f, //radius of camera's distance from earth planetRadius; //determine and set the camera coordinates, focal point float camX = planetX + (float) (camOffset * Math.cos(rotation)), camZ = planetZ + (float) (camOffset * Math.sin(rotation)); System.out.println("Camera located at < " + camX + ", 1, " + camZ + " >"); System.out.println("Camera focused at < " + planetX + ", 1, " + planetZ + " >"); glu.gluLookAt(camX, 0.0f, camZ, planetX, 0.0f, planetZ, 0.0f, 1.0f, 0.0f); //Draw each planet for(Planet art : artbook) { returnToOrigin(); gl.glTranslatef(planetX, 0.0f, planetZ); //orbit gl.glRotatef(-rotation, 0.0f, 1.0f, 0.0f); //rotation setColor(art); glu.gluSphere(quad, planetRadius, 10, 10); } frameCount += 1; }
orbitPlanet函数
private void orbitPlanet(Planet art) { float sunRadius = 109.3f, radius = art.getRadius(), offset = art.getOffset(), orbit; //if the planet isn't the sun, skew the offset float skew = sunRadius + radius; if(radius != sunRadius) offset += skew; //Get the new orbital position of the planet orbit = art.orbit(frameCount) % 360; //set the position of the planet float x = (float) (offset * Math.cos(Math.toRadians(orbit))); float z = (float) (offset * Math.sin(Math.toRadians(orbit))); art.setX(x); art.setZ(z); }
Planet类的orbit方法
public float orbit(float frameCount) { //find the new orbit angle theta and the delta between the current and new orbit float theta = frameCount * 1/(this.orbitRate); this.orbit = theta; return this.orbit; }
内容的提问来源于stack exchange,提问作者Red Richardson
相关产品推荐
相关产品推荐

