mirror of
https://github.com/octoleo/plantuml.git
synced 2024-06-12 05:02:24 +00:00
154 lines
3.3 KiB
Java
154 lines
3.3 KiB
Java
package zext.plantuml.com.ctreber.acearth.util;
|
|
|
|
import java.io.IOException;
|
|
import java.io.Writer;
|
|
|
|
/**
|
|
* <p>
|
|
* Latitude and longitude coordinate. Can be used as declination and right
|
|
* ascension as well.
|
|
*
|
|
* <p>
|
|
* © 2002 Christian Treber, ct@ctreber.com
|
|
*
|
|
* @author Christian Treber, ct@ctreber.com
|
|
*
|
|
*/
|
|
public class Coordinate {
|
|
/*
|
|
* MeanObliquity gives the mean obliquity of the earth's axis at epoch
|
|
* 1990.0 (computed as 23.440592 degrees according to the method given in
|
|
* duffett-smith, section 27)
|
|
*/
|
|
private static final double MEAN_OBLIQUITY = 23.440592 * Toolkit.TWOPI / 360;
|
|
|
|
// Or DE
|
|
private double fLat;
|
|
// Or RA
|
|
private double fLong;
|
|
|
|
public Coordinate() {
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Construct a location specfied by two angles. Your choice if in degrees or
|
|
* rads, but keep track!
|
|
*
|
|
* @param pLong
|
|
* Longitude or RA
|
|
* @param pLat
|
|
* Latitude or DE
|
|
*/
|
|
public Coordinate(double pLat, double pLong) {
|
|
fLat = pLat;
|
|
fLong = pLong;
|
|
}
|
|
|
|
public void renderAsXML(Writer writer) throws IOException {
|
|
writer.write("<Coordinate>\n");
|
|
writer.write(" <latitude>" + fLat + "</latitude>\n");
|
|
writer.write(" <longitude>" + fLong + "</longitude>\n");
|
|
writer.write("</Coordinate>\n");
|
|
}
|
|
|
|
public Point3D getPoint3D() {
|
|
final double lLatRad = Toolkit.degsToRads(fLat);
|
|
final double lLongRad = Toolkit.degsToRads(fLong);
|
|
|
|
final double lX = Math.cos(lLatRad) * Math.sin(lLongRad);
|
|
final double lY = Math.sin(lLatRad);
|
|
final double lZ = Math.cos(lLatRad) * Math.cos(lLongRad);
|
|
|
|
return new Point3D(lX, lY, lZ);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Assumes coordinate is not in degrees but rads.
|
|
*
|
|
* @return
|
|
*/
|
|
public Point3D getPoint3DRads() {
|
|
final double lX = Math.cos(fLat) * Math.sin(fLong);
|
|
final double lY = Math.sin(fLat);
|
|
final double lZ = Math.cos(fLat) * Math.cos(fLong);
|
|
|
|
return new Point3D(lX, lY, lZ);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Convert from ecliptic to equatorial coordinates (after duffett-smith,
|
|
* section 27)
|
|
*/
|
|
public Coordinate eclipticToEquatorial() {
|
|
final double sin_e = Math.sin(MEAN_OBLIQUITY);
|
|
final double cos_e = Math.cos(MEAN_OBLIQUITY);
|
|
|
|
final double lRA = Math.atan2(Math.sin(fLong) * cos_e - Math.tan(fLat) * sin_e, Math.cos(fLong));
|
|
final double lDE = Math.asin(Math.sin(fLat) * cos_e + Math.cos(fLat) * sin_e * Math.sin(fLong));
|
|
|
|
return new Coordinate(lDE, lRA);
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Add position to this position, make sure coordinates are valid.
|
|
*/
|
|
public void add(Coordinate lOther) {
|
|
fLat += lOther.fLat;
|
|
fLong += lOther.fLong;
|
|
wrap();
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Warp coordinates exceeding valid values. Happens when latitudes and
|
|
* longitudes are added or substracted.
|
|
*/
|
|
public void wrap() {
|
|
if (fLat > 90) {
|
|
fLat = 180 - fLat;
|
|
fLong += 180;
|
|
} else if (fLat < -90) {
|
|
fLat = -180 - fLat;
|
|
fLong += 180;
|
|
}
|
|
|
|
if (fLong > 180) {
|
|
do {
|
|
fLong -= 360;
|
|
} while (fLong > 180);
|
|
} else if (fLong < -180) {
|
|
do {
|
|
fLong += 360;
|
|
} while (fLong < -180);
|
|
}
|
|
}
|
|
|
|
public double getLat() {
|
|
return fLat;
|
|
}
|
|
|
|
public double getDE() {
|
|
return fLat;
|
|
}
|
|
|
|
public double getLong() {
|
|
return fLong;
|
|
}
|
|
|
|
public double getRA() {
|
|
return fLong;
|
|
}
|
|
|
|
public boolean check() {
|
|
return (-90 <= fLat) && (fLat <= 90) && (-180 <= fLong) && (fLong <= 180);
|
|
}
|
|
|
|
public String toString() {
|
|
return "lat: " + fLat + ", long: " + fLong;
|
|
}
|
|
}
|