package ext.plantuml.com.ctreber.acearth; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import ext.plantuml.com.ctreber.acearth.gui.CanvasACearth; import ext.plantuml.com.ctreber.acearth.plugins.Plugin; import ext.plantuml.com.ctreber.acearth.plugins.markers.Marker; import ext.plantuml.com.ctreber.acearth.plugins.markers.PluginMarkers; import ext.plantuml.com.ctreber.acearth.projection.Projection; import ext.plantuml.com.ctreber.acearth.projection.ProjectionCyl; import ext.plantuml.com.ctreber.acearth.projection.ProjectionMerc; import ext.plantuml.com.ctreber.acearth.projection.ProjectionOrtho; import ext.plantuml.com.ctreber.acearth.renderer.Renderer; import ext.plantuml.com.ctreber.acearth.renderer.RowTypeRendererScanBit; import ext.plantuml.com.ctreber.acearth.renderer.RowTypeRendererScanDot; import ext.plantuml.com.ctreber.acearth.scanbit.BitGeneratorMap; import ext.plantuml.com.ctreber.acearth.scanbit.BitGeneratorMapDefault; import ext.plantuml.com.ctreber.acearth.scanbit.BitGeneratorMapOrtho; import ext.plantuml.com.ctreber.acearth.scandot.DotGeneratorLines; import ext.plantuml.com.ctreber.acearth.scandot.DotGeneratorStars; import ext.plantuml.com.ctreber.acearth.scandot.ScanDot; import ext.plantuml.com.ctreber.acearth.scandot.ScanDotGenerator; import ext.plantuml.com.ctreber.acearth.shader.Shader; import ext.plantuml.com.ctreber.acearth.shader.ShaderDefault; import ext.plantuml.com.ctreber.acearth.shader.ShaderFlat; import ext.plantuml.com.ctreber.acearth.shader.ShaderOrtho; import ext.plantuml.com.ctreber.acearth.util.Coordinate; import ext.plantuml.com.ctreber.acearth.util.SunPositionCalculator; import ext.plantuml.com.ctreber.acearth.util.Toolkit; import ext.plantuml.com.ctreber.aclib.sort.CTSort; import ext.plantuml.com.ctreber.aclib.sort.QuickSort; /** *
* The original XEarth was written by Kirk Johnson in July 1993 - thank you for * writing this great little program and making it available for free! * *
* I wanted to extend the program, but not in C. So I created this Java version,
* and found the process quite painfull interesting. The
* biggest effort went into resolving references between C files and
* eliminatiing pointers.
*
*
* AC.earth Copyright (c) 2002 Christian Treber, ct@ctreber.com * *
* AC.earth is based on XEarth by Kirk Johnson * *
* To comply with the XEarth license I include the following text: * *
* XEarth Copyright (C) 1989, 1990, 1993-1995, 1999 Kirk Lauritz Johnson * Parts of the source code are: * Copyright (C) 1989, 1990, 1991 by Jim Frost * Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com> * Permission to use, copy, modify and freely distribute xearth for * non-commercial and not-for-profit purposes is hereby granted * without fee, provided that both the above copyright notice and this * permission notice appear in all copies and in supporting * documentation. * [Section refering to GIF omitted because it doesn't apply to this version] * The author makes no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ** *
* The license for this program (AC.earth) is the same as the quoted license * above, with one change: The "copyright notice and permission notice" shall * include the entire text of this section. * * todo Phase 2: Make grid value stuff more meaningful ("every n degrees") todo * Phase 2: Enter fixed time as data and time, not seconds since epoch todo * Phase 2: Compact map data into binary file * *
* © 2002 Christian Treber, ct@ctreber.com * * @author Christian Treber, ct@ctreber.com */ public class ACearth { // :: remove folder when WASM public static final String VERSION = "1.1"; public static final String BUILD = "22.11.2002 004"; // private static long fsStartTime = 0; private ConfigurationACearth fConf = new ConfigurationACearth(); private long fCurrentTime; private CanvasACearth fCanvas; private Coordinate fViewPos; private double fViewRotation; private List fPlugins; /** *
* Well, the main class.
*
* @param markers
*/
public ACearth(List
* This is repeated when time changes since this influences the position of
* Earth.
*/
private void computePositions() {
// Determine time for rendering
if (fConf.getInt("fixedTime") == 0) {
// No fixed time.
// final long lTimePassed = System.currentTimeMillis() - fsStartTime;
// fCurrentTime = fsStartTime + (long) (fConf.getDouble("timeWarpFactor") *
// lTimePassed);
fCurrentTime = System.currentTimeMillis();
} else {
// Fixed time.
fCurrentTime = fConf.getInt("fixedTime") * 1000L;
}
if (fConf.getBoolean("sunMovesP")) {
fConf.setSunPos(SunPositionCalculator.getSunPositionOnEarth(fCurrentTime));
}
// Determine viewing position
if (fConf.is("viewPositionType", "Fixed")) {
fViewPos = fConf.getViewPos();
} else if (fConf.is("viewPositionType", "Sun-relative")) {
fViewPos = getSunRelativePosition();
} else if (fConf.is("viewPositionType", "Orbit")) {
fViewPos = getOrbitPosition(fCurrentTime);
} else if (fConf.is("viewPositionType", "Random")) {
fViewPos = getRandomPosition();
} else if (fConf.is("viewPositionType", "Moon")) {
fViewPos = SunPositionCalculator.getMoonPositionOnEarth(fCurrentTime);
}
// for ViewRotGalactic, compute appropriate viewing rotation
if (fConf.is("viewRotationType", "Galactic")) {
fViewRotation = (Toolkit.degsToRads(
fConf.getSunPos().getLat() * Math.sin((fViewPos.getLong() - fConf.getSunPos().getLong()))));
} else {
fViewRotation = fConf.getDouble("viewRotation");
}
}
/**
*
* Add sun position and position relative to sun, straighten out the result.
*
* @return Position relativ to sun position as defined by fSunPosRel.
*/
private Coordinate getSunRelativePosition() {
final Coordinate lPos = fConf.getSunPos();
lPos.add(fConf.getSunPosRel());
return lPos;
}
private Coordinate getOrbitPosition(long pTimeMillis) {
double x, y, z;
double a, c, s;
double t1, t2;
/* start at 0 N 0 E */
x = 0;
y = 0;
z = 1;
/*
* rotate in about y axis (from z towards x) according to the number of orbits
* we've completed
*/
a = (double) pTimeMillis / (fConf.getDouble("orbitPeriod") * 3600 * 1000) * 2 * Math.PI;
c = Math.cos(a);
s = Math.sin(a);
t1 = c * z - s * x;
t2 = s * z + c * x;
z = t1;
x = t2;
/*
* rotate about z axis (from x towards y) according to the inclination of the
* orbit
*/
a = Toolkit.degsToRads(fConf.getDouble("orbitInclination"));
c = Math.cos(a);
s = Math.sin(a);
t1 = c * x - s * y;
t2 = s * x + c * y;
x = t1;
y = t2;
/*
* rotate about y axis (from x towards z) according to the number of rotations
* the earth has made
*/
a = ((double) pTimeMillis / 86400000) * (2 * Math.PI);
c = Math.cos(a);
s = Math.sin(a);
t1 = c * x - s * z;
t2 = s * x + c * z;
x = t1;
z = t2;
return new Coordinate(Toolkit.radsToDegs(Math.asin(y)), Toolkit.radsToDegs(Math.atan2(x, z)));
}
/**
*
* Pick a position (lat, lon) at random
*
* @return A random position.
*/
private static Coordinate getRandomPosition() {
/* select a vector at random */
final double[] pos = new double[3];
double mag = 0;
do {
for (int i = 0; i < 3; i++) {
pos[i] = ((Math.random() * 20000) * 1e-4) - 1;
mag += pos[i] * pos[i];
}
} while ((mag > 1.0) || (mag < 0.01));
/* normalize the vector */
mag = Math.sqrt(mag);
for (int i = 0; i < 3; i++) {
pos[i] /= mag;
}
/* convert to (lat, lon) */
final double s_lat = pos[1];
final double c_lat = Math.sqrt(1 - s_lat * s_lat);
final double s_lon = pos[0] / c_lat;
final double c_lon = pos[2] / c_lat;
return new Coordinate(Math.atan2(s_lat, c_lat) * (180 / Math.PI), Math.atan2(s_lon, c_lon) * (180 / Math.PI));
}
// public static long getStartTime() {
// return fsStartTime;
// }
public ConfigurationACearth getConf() {
return fConf;
}
}