/* File: KeplerEquation.java University of Applied Science Berne,HTA-Biel/Bienne, Computer Science Department. Diploma thesis J3D Solar System Simulator Originally written by Marcel Portner & Bernhard Hari (c) 2000 CVS - Information : $Header: /var/cvsreps/projects/c450/2000/sss3d/source_diploma/sss3d/calculations/keplerequation/KeplerEquation.java,v 1.10 2000/12/13 13:36:38 portm Exp $ $Author: portm $ $Date: 2000/12/13 13:36:38 $ $State: Exp $ */ package sss3d.calculations.keplerequation; import sss3d.calculations.constants.AstronomicalConstants; import sss3d.utils.SSS3dConstants; import sss3d.utils.astronomy.*; import sss3d.calculations.*; import sss3d.contentbranch.*; import javax.vecmath.Point3f; import javax.vecmath.Matrix3d; /** * Used to calculate the planet positions using kepler equation.
* This part is left as a exercise for the diploma work, at the end of * October 2000. We use the simpler ellipse equation method instead. * For example: *
 *    use : 
 *    KeplerEquation keplereq = new KeplerEquation();
 *    Point3f [] positions = keplereq.getPositions(CelestialObjectInfo,time);
 * 
* * @author Marcel Portner & Bernhard Hari * @version $Revision: 1.10 $ * @see sss3d.calculations.ellipseequation.EllipseEquation */ public class KeplerEquation extends OrbitCalculator { private CelestialObjectInfo objInfo; private double jDay; private boolean compressed; private boolean kepler; private int nbrOfPoints; private Point3f[] positions; /** * Returns the positions of the given planet. * The algorithm used is the kepler equation. * * @param objInfo Information about the planet. * @param jDay calculates positions corresponding to the given julian day * @param compressed true if the universe is logorithmic compressed or false if * it has the real proportion. * @return Point3f[] an array of vectors containing the positions. */ public Point3f[] getPositions(CelestialObjectInfo objInfo, double jDay, boolean compressed) { this.objInfo = objInfo; // modifiziertes julianisches Datum this.jDay = jDay - 2400000.5; this.compressed = compressed; kepler = false; // last is used to mark the end of the array. nbrOfPoints = objInfo.getNbrOfPositions(); positions = new Point3f[nbrOfPoints]; String type = objInfo.getType(); if(type.equals(SSS3dConstants.TYPES[SSS3dConstants.PLANET_TYPE])) { int planetNr = -1; String name = objInfo.getName(); if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.MERCURY])) { planetNr = SSS3dConstants.MERCURY; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.VENUS])) { planetNr = SSS3dConstants.VENUS; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.EARTH])) { planetNr = SSS3dConstants.EARTH; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.MARS])) { planetNr = SSS3dConstants.MARS; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.JUPITER])) { planetNr = SSS3dConstants.JUPITER; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.SATURN])) { planetNr = SSS3dConstants.SATURN; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.URANUS])) { planetNr = SSS3dConstants.URANUS; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.NEPTUNE])) { planetNr = SSS3dConstants.NEPTUNE; } else if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.PLUTO])) { planetNr = SSS3dConstants.PLUTO; } else { System.out.println("Error in KeplerEquation: planet not knowned"); return null; } calcPlanetPos(planetNr); } else if(type.equals(SSS3dConstants.TYPES[SSS3dConstants.MOON_TYPE])) { String name = objInfo.getName(); if(name.equals(SSS3dConstants.CELESTIAL[SSS3dConstants.MOON])) { calcOurMoonPos(); } else { calcMoonPos(); } } else if(type.equals(SSS3dConstants.TYPES[SSS3dConstants.COMET_TYPE])) { calcCometPos(); } else { System.out.println("Error in KeplerEquation: Other not supported yet"); return null; } return positions; } /** * Returns an array of positons for the given positions, based * on the given jDay.
* * @param objPos actual positions of the object. * @param jDay calculates positions corresponding to the given julian day * @param compressed true if the universe is logorithmic compressed or false if * it has the real proportion. * @return Point3f[] an array of vectors containing the points */ public Point3f[] updatePositions(Point3f[] objPos, double jDay, boolean compressed) { return objPos; } /** * Calculate the positions of the given planet as kepler ellipse. * * @param planetNr the planet number for the identification. */ private void calcPlanetPos(int planetNr) { double step = objInfo.getOrbitPeriod() / (double)nbrOfPoints * AstronomicalConstants.DAYS; Planets planet = new Planets(); PrecNut prec = new PrecNut(); for(int i = 0; i < nbrOfPoints; i++) { double time = ((double)i * step + jDay - AstronomicalConstants.MJD_J2000) / 36525.0; Vec3D planpos; if(kepler) { planpos = planet.kepPosition(planetNr, time); } else { planpos = planet.pertPosition(planetNr, time); } // logarithmic or scalar !!! if(compressed) { planpos.scaleDistance(compressed, 5.0); } else { planpos.scaleDistance(compressed, AstronomicalConstants.AU / SSS3dConstants.SCALE); } // Praezession und aequatoriale Koordinaten Matrix3d p = prec.precMatrix_Ecl(time, AstronomicalConstants.T_J2000); planpos.mul(p); positions[i] = new Point3f((float) planpos.x, (float) planpos.z, (float)-planpos.y); } } /** * Calculate the positions of our moon. */ private void calcOurMoonPos() { double step = objInfo.getOrbitPeriod() / (double)nbrOfPoints; Moon moon = new Moon(); for(int i = 0; i < nbrOfPoints; i++) { double time = ((double)i * step + jDay - AstronomicalConstants.MJD_J2000) / 36525.0; Vec3D moonpos = moon.moonEqu(time); // logarithmic or scalar !!! if(compressed) { moonpos.scaleDistance(compressed, 3e-6); } else { moonpos.scaleDistance(compressed, 1 / SSS3dConstants.SCALE); } positions[i] = new Point3f((float) moonpos.x, (float) moonpos.z, (float)-moonpos.y); } } /** * Calculate the positions of any moon as a circle. */ private void calcMoonPos() { double x, y, z, phi, r; if(compressed) { r = StrictMath.log(objInfo.getDistance() / 1000) / 5; } else { r = objInfo.getDistance() / SSS3dConstants.SCALE; } double theta = StrictMath.toRadians(objInfo.getOrbitInclinationToEcliptic()); for(int i = 0; i < nbrOfPoints; i++) { phi = ((double)i / nbrOfPoints) * MoreMath.PI2; x = r * StrictMath.cos(phi); z = -r * StrictMath.sin(phi); y = -x * StrictMath.tan(theta); positions[i] = new Point3f((float)x, (float)y, (float)z); } } /** * Calculate the positions of any comet as kepler ellipse. */ private void calcCometPos() { double step = objInfo.getOrbitPeriod() / (double)nbrOfPoints * AstronomicalConstants.DAYS; Kepler kepler = new Kepler(); PrecNut prec = new PrecNut(); Matrix3d pqr = kepler.gaussVec(MoreMath.RAD * objInfo.getLongitudeNode(), MoreMath.RAD * objInfo.getOrbitInclinationToEcliptic(), MoreMath.RAD * objInfo.getPerihelion()); pqr.mul(prec.precMatrix_Ecl((objInfo.getEquinox() - 2000.0) / 100.0, (2000.0 - 2000.0) / 100.0)); for(int i = 0; i < nbrOfPoints; i++) { double time = (double)i * step + jDay; Vec3D[] vec = kepler.kepler(AstronomicalConstants.GM_SUN, objInfo.getEpoch(), time, objInfo.getDistance(), objInfo.getOrbitEccentricity(), pqr); // logarithmic or scalar !!! if(compressed) { vec[0].scaleDistance(compressed, 5.0); } else { vec[0].scaleDistance(compressed, AstronomicalConstants.AU / SSS3dConstants.SCALE); } positions[i] = new Point3f((float) vec[0].x, (float) vec[0].z, (float)-vec[0].y); } } }