我一直在研究太阳系的动画。到目前为止,我已经让行星围绕太阳旋转。现在我想让它们以近日点和远日点的椭圆形旋转,以便行星朝向和远离太阳移动。
我理解背后的数学有一些问题。我见过像this one这样的例子,他只使用GL_LINE_LOOP绘制椭圆。我从FloatUtil类中使用makeRotationAxis()和makeTranslation(),并使用时间来判断旋转的速度。我认为我的代码比我能表达的更多,所以我们在这里(我已经使用下面评论的椭圆方程编辑了代码)。
编辑:我修复了一些错误并简化了代码(同样,行星在X轴和Z轴上移动,这就是为什么makeTranslation(..,..,tx,0f,ty);),但我仍然无法得到椭圆轨道,现在行星的旋转是循环的。
主要班级:
.....
//Inside init()
// Store the starting time of the application
start = System.currentTimeMillis();
// The planets rotational speed around the planet's own axis (planetary day)
float[] ownRotation = {15.0f, 10.0f, 06.0f, 03.0f, 02.0f, 01.5f, 00.5f, 00.2f, 00.1f};
// The planets rotational speed around the Sun's axis (planetary year)
float[] sunRotation = {10.0f, 08.0f, 06.0f, 04.0f, 02.0f, 01.3f, 01.0f, 00.5f, 00.2f};
// The planets distance from the Sun on the X axis
float[] xDistanceFromSun = {1.6f, 4.0f, 9.0f, 13.0f, 20.0f, 24.0f, 27.0f, 30.0f, 34.0f};
// The planets distance from the Sun on the Y axis
float[] zDistanceFromSun = {0.8f, 2.0f, 4.5f, 6.5f, 10.0f, 12.0f, 13.5f, 15.0f, 17.0f};
// The scale size of the planets
float[] scale = {0.2f, 0.3f, 0.5f, 0.2f, 1.2f, 1.2f, 1.0f, 0.4f, 0.1f};
// The sun object, specifies it's rotation
sun = new Sun(0.5f, 1f);
// Make the planet objects and put them in the array
for(int i = 0; i < scale.length; i++)
planets.add(new Planet( ownRotation[i],
sunRotation[i],
xDistanceFromSun[i],
zDistanceFromSun[i],
scale[i]
));
// Make the moon object
moon = new Moon(
planets.get(2).getPlanetMatrix(),
1.0f,
02.0f,
0.3f);
}
.....
// Inside display()
long now = System.currentTimeMillis();
// Find a time delta for the time passed since the start of execution
float diff = (float) (now - start) / 10000;
// Copy the Sun's matrix to the server
pointer[0].asFloatBuffer().put(sun.getSunMatrix());
// Update the Sun's Matrix
sun.updateSun(diff);
// Copy the plantes's matrixes to the server and then update them
for(int i = 0; i < 9; i++) {
pointer[i+1].asFloatBuffer().put(planets.get(i).getPlanetMatrix());
planets.get(i).updatePlanet(diff);
}
// Copy the moon's matrix to the server
pointer[10].asFloatBuffer().put(moon.getMoonMatrix());
// Update the Moon's Matrix
moon.updateMoon(diff, planets.get(2).getPlanetMatrix());
.....
星球类:
public class Planet {
private float sunRotation;
private float ownRotation;
private float diff;
private float[] ownRotationMatrix;
private float[] sunRotationMatrix;
private float[] scaleMatrix;
private float[] ellipticRotationMatrix;
private float[] planetMatrix;
/**
* @param ownRotation The planet's rotation around it's own axis
* @param sunRotation The planet's rotation around the Sun
* @param xDistance The distance from the Planet to the Sun at X = max/min
* @param zDistance The distance from the Planet to the Sun at Y = max/min
* @param scale The scale/size of the Planet
*/
public Planet (float ownRotation, float sunRotation, float xDistance, float zDistance, float scale) {
// Set the values
this.ownRotation = ownRotation;
this.sunRotation = sunRotation;
// Create the matrixes needed
setOwnRotationMatrix(ownRotation);
setSunRotationMatrix(sunRotation);
setEllipticRotationMatrix(xDistance, zDistance);
setScaleMatrix(scale);
// Create the planet matrix
createPlanet();
}
public void setOwnRotationMatrix(float ownRotation) {
this.ownRotationMatrix = FloatUtil.makeRotationAxis(new float[16], 0, ownRotation, 0f, 1f, 0f, new float[3]);
}
public void setSunRotationMatrix(float sunRotation) {
this.sunRotationMatrix = FloatUtil.makeRotationAxis(new float[16], 0, sunRotation, 0f, 1f, 0f, new float[3]);
}
public void setScaleMatrix(float scale) {
this.scaleMatrix = FloatUtil.makeScale(new float[16], false, scale, scale, scale);
}
// tx = a*sin(ang_rad) + sqrt(a*a-b*b);
// tz = b*cos(ang_rad);
public void setEllipticRotationMatrix(float xDistance, float zDistance) {
float tx = (float)(xDistance * Math.sin(diff) + Math.sqrt(xDistance * xDistance - zDistance * zDistance));
float tz = (float)(zDistance * Math.cos(diff));
System.out.println("tx: " + tx);
System.out.println("tz: " + tz);
this.ellipticRotationMatrix = FloatUtil.makeTranslation(new float[16], false, tx, 0f, tz);
}
public void createPlanet() {
this.planetMatrix =
FloatUtil.multMatrix(
FloatUtil.multMatrix(
FloatUtil.multMatrix(
sunRotationMatrix,
ellipticRotationMatrix,
new float[16]
),
ownRotationMatrix,
new float[16]
),
scaleMatrix,
new float[16]
);
}
public void updatePlanet(float diff) {
setOwnRotationMatrix(ownRotation * diff);
setSunRotationMatrix(sunRotation * diff);
createPlanet();
}
public float[] getOwnRotationMatrix() {
return this.ownRotationMatrix;
}
public float[] getPlanetMatrix() {
return this.planetMatrix;
}
}