253 lines
9.5 KiB
Java
253 lines
9.5 KiB
Java
|
/*
|
||
|
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.<br>
|
||
|
* 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:
|
||
|
* <pre>
|
||
|
* use :
|
||
|
* KeplerEquation keplereq = new KeplerEquation();
|
||
|
* Point3f [] positions = keplereq.getPositions(CelestialObjectInfo,time);
|
||
|
* </pre>
|
||
|
*
|
||
|
* @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.<br>
|
||
|
*
|
||
|
* @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);
|
||
|
}
|
||
|
}
|
||
|
}
|