From 0eba95c483f2db216116ed8ebc99848415d04b3f Mon Sep 17 00:00:00 2001 From: sesteves <sroesteves@gmail.com> Date: Sun, 10 Jul 2016 16:40:03 +0100 Subject: [PATCH] multiple improvements --- .../AtmosphericRefraction.java | 3 +- .../MultiLayerModel.java | 90 +++++++++++++------ 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java b/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java index 4e5e0ba0..837f259a 100644 --- a/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java +++ b/src/main/java/org/orekit/rugged/atmosphericrefraction/AtmosphericRefraction.java @@ -19,6 +19,7 @@ package org.orekit.rugged.atmosphericrefraction; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.orekit.rugged.raster.Tile; +import org.orekit.rugged.utils.NormalizedGeodeticPoint; /** * Interface for atmospheric refraction. @@ -26,6 +27,6 @@ import org.orekit.rugged.raster.Tile; */ public interface AtmosphericRefraction { - double getDeviation(Vector3D pos, Vector3D los, Vector3D zenith, double altitude, Tile tile); + NormalizedGeodeticPoint getPointOnGround(Vector3D pos, Vector3D los, Vector3D zenith, double altitude, Tile tile); } diff --git a/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java b/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java index 1ebaa007..a7d7a1bc 100644 --- a/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java +++ b/src/main/java/org/orekit/rugged/atmosphericrefraction/MultiLayerModel.java @@ -18,13 +18,17 @@ package org.orekit.rugged.atmosphericrefraction; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.util.FastMath; +import org.orekit.bodies.OneAxisEllipsoid; +import org.orekit.errors.OrekitException; +import org.orekit.frames.FramesFactory; +import org.orekit.rugged.errors.RuggedException; import org.orekit.rugged.raster.Tile; import org.orekit.rugged.utils.ExtendedEllipsoid; import org.orekit.rugged.utils.NormalizedGeodeticPoint; +import org.orekit.utils.Constants; +import org.orekit.utils.IERSConventions; -import java.util.Collections; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; /** * Multi layer model for atmospheric refraction. @@ -33,7 +37,9 @@ import java.util.TreeMap; public class MultiLayerModel implements AtmosphericRefraction { // maps altitude (lower bound) to refraction index - private static final Map<Double, Double> meanAtmoshpericRefractions; + private static final Map<Double, Double> meanAtmosphericRefractions; + + private static final Map<Double, ExtendedEllipsoid> atmosphericEllipsoids; static { Map<Double, Double> refractions = new TreeMap(Collections.reverseOrder()); @@ -52,35 +58,69 @@ public class MultiLayerModel implements AtmosphericRefraction { refractions.put(40000.00000000000, 1.00000100000); refractions.put(50000.00000000000, 1.00000000000); refractions.put(100000.00000000000, 1.00000000000); - meanAtmoshpericRefractions = Collections.unmodifiableMap(refractions); + meanAtmosphericRefractions = Collections.unmodifiableMap(refractions); + + Map<Double, ExtendedEllipsoid> ellipsoids = new HashMap<Double, ExtendedEllipsoid>(); + try { + for (Double altitude : refractions.keySet()) { + OneAxisEllipsoid ellipsoid = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS + altitude, + Constants.WGS84_EARTH_FLATTENING, FramesFactory.getITRF(IERSConventions.IERS_2010, true)); + ellipsoid = new ExtendedEllipsoid(ellipsoid.getEquatorialRadius(), ellipsoid.getFlattening(), + ellipsoid.getBodyFrame()); + ellipsoids.put(altitude, (ExtendedEllipsoid) ellipsoid); + } + } catch (OrekitException e) { + e.printStackTrace(); + } + atmosphericEllipsoids = Collections.unmodifiableMap(ellipsoids); } @Override - public double getDeviation(Vector3D pos, Vector3D los, Vector3D zenith, double altitude, Tile tile) { + public NormalizedGeodeticPoint getPointOnGround(Vector3D initialPos, Vector3D initialLos, Vector3D initialZenith, + double altitude, Tile tile) { + NormalizedGeodeticPoint newGeodeticPoint = null; + try { - new ExtendedEllipsoid(ellipsoid.getEquatorialRadius(), ellipsoid.getFlattening(), - ellipsoid.getBodyFrame()); + Vector3D pos = initialPos; + Vector3D los = initialLos; + Vector3D zenith = initialZenith; + double theta1 = Vector3D.angle(los, zenith), theta2; + double previousRefractionIndex = -1; + NormalizedGeodeticPoint gp = null; + for (Map.Entry<Double, Double> entry : meanAtmosphericRefractions.entrySet()) { + if (pos.getZ() < entry.getKey()) { + continue; + } - double incidenceAngleSin = FastMath.sin(Vector3D.angle(los, zenith)); - double previousRefractionIndex = -1; - double xDistance = 0; - for(Map.Entry<Double, Double> entry : meanAtmoshpericRefractions.entrySet()) { - if(pos.getZ() < entry.getKey()) { - continue; - } - if(previousRefractionIndex > 0) { - incidenceAngleSin = previousRefractionIndex * incidenceAngleSin / entry.getValue(); - } - xDistance += (pos.getZ() - entry.getKey()) * FastMath.tan(incidenceAngleSin); + if (previousRefractionIndex > 0) { + theta2 = previousRefractionIndex * FastMath.sin(theta1) / entry.getValue(); - if(altitude > entry.getKey()) { - break; + // get current los + double a = FastMath.sqrt((1 - FastMath.pow(FastMath.cos(theta2), 2)) / + (1 - FastMath.pow(FastMath.cos(theta1), 2))); + double b = a * FastMath.cos(theta1) - FastMath.cos(theta2); + los = new Vector3D(a, los, b, zenith); + + theta1 = theta2; + } + + // get intersection point + ExtendedEllipsoid ellipsoid = atmosphericEllipsoids.get(entry.getKey()); + gp = ellipsoid.pointOnGround(pos, los, 0.0); + pos = ellipsoid.transform(gp); + zenith = gp.getZenith(); + + if (altitude > entry.getKey()) { + break; + } + previousRefractionIndex = entry.getValue(); } - previousRefractionIndex = entry.getValue(); - } - NormalizedGeodeticPoint geodeticPoint = tile.cellIntersection(pos, los, 0, 0); + newGeodeticPoint = tile.cellIntersection(gp, los, 0, 0); + } catch (RuggedException e) { + e.printStackTrace(); + } - return pos.getX() + xDistance; + return newGeodeticPoint; } } -- GitLab