使对象在JOGL中以椭圆形旋转

时间:2017-11-11 14:42:51

标签: opengl jogl ellipse

我一直在研究太阳系的动画。到目前为止,我已经让行星围绕太阳旋转。现在我想让它们以近日点和远日点的椭圆形旋转,以便行星朝向和远离太阳移动。

我理解背后的数学有一些问题。我见过像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;
    }
}

0 个答案:

没有答案