From 08ad7cf3ea141400d582c460092283c369c8985b Mon Sep 17 00:00:00 2001
From: Luc Maisonobe <luc@orekit.org>
Date: Mon, 5 May 2014 11:10:37 +0200
Subject: [PATCH] Slightly changed the intersection refinement in flat-body.

---
 .../orekit/rugged/core/ExtendedEllipsoid.java | 24 +++++++++++++++++++
 .../core/duvenhage/DuvenhageAlgorithm.java    |  5 ++--
 .../rugged/core/ExtendedEllipsoidTest.java    |  6 +++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/orekit/rugged/core/ExtendedEllipsoid.java b/src/main/java/org/orekit/rugged/core/ExtendedEllipsoid.java
index b64fa130..a6c7dcfb 100644
--- a/src/main/java/org/orekit/rugged/core/ExtendedEllipsoid.java
+++ b/src/main/java/org/orekit/rugged/core/ExtendedEllipsoid.java
@@ -246,4 +246,28 @@ public class ExtendedEllipsoid extends OneAxisEllipsoid {
 
     }
 
+    /** Convert a line-of-sight from Cartesian to topocentric.
+     * @param primary reference point on the line-of-sight (in body frame and Cartesian coordinates)
+     * @param secondary secondary point on the line-of-sight, only used to define a direction
+     * with respect to the primary point (in body frame and Cartesian coordinates)
+     * @return line-of-sight in topocentric frame (East, North, Zenith) of the point,
+     * scaled to match radians in the horizontal plane and meters along the vertical axis
+     * @exception RuggedException if points cannot be converted to geodetic coordinates
+     */
+    public Vector3D convertLos(final Vector3D primary, final Vector3D secondary)
+        throws RuggedException {
+        try {
+
+            // switch to geodetic coordinates using primary point as reference
+            final GeodeticPoint point = transform(primary, getBodyFrame(), null);
+            final Vector3D      los   = secondary.subtract(primary);
+
+            // convert line of sight
+            return convertLos(point, los);
+
+        } catch (OrekitException oe) {
+            throw new RuggedException(oe, oe.getSpecifier(), oe.getParts());
+        }
+    }
+
 }
diff --git a/src/main/java/org/orekit/rugged/core/duvenhage/DuvenhageAlgorithm.java b/src/main/java/org/orekit/rugged/core/duvenhage/DuvenhageAlgorithm.java
index e128456f..8b9f3097 100644
--- a/src/main/java/org/orekit/rugged/core/duvenhage/DuvenhageAlgorithm.java
+++ b/src/main/java/org/orekit/rugged/core/duvenhage/DuvenhageAlgorithm.java
@@ -154,12 +154,13 @@ public class DuvenhageAlgorithm implements IntersectionAlgorithm {
         try {
             if (flatBody) {
                 // under the (bad) flat-body assumption, the reference point must remain
-                // at DEM entry, even if we already have a much better close guess :-(
+                // at DEM entry and exit, even if we already have a much better close guess :-(
                 // this is in order to remain consistent with other systems
                 final Tile tile = cache.getTile(closeGuess.getLatitude(), closeGuess.getLongitude());
+                final Vector3D      exitP  = ellipsoid.pointAtAltitude(position, los, tile.getMinElevation());
                 final Vector3D      entryP = ellipsoid.pointAtAltitude(position, los, tile.getMaxElevation());
                 final GeodeticPoint entry  = ellipsoid.transform(entryP, ellipsoid.getBodyFrame(), null);
-                return tile.pixelIntersection(entry, ellipsoid.convertLos(entry, los),
+                return tile.pixelIntersection(entry, ellipsoid.convertLos(entryP, exitP),
                                               tile.getLatitudeIndex(closeGuess.getLatitude()),
                                               tile.getLongitudeIndex(closeGuess.getLongitude()));
             } else {
diff --git a/src/test/java/org/orekit/rugged/core/ExtendedEllipsoidTest.java b/src/test/java/org/orekit/rugged/core/ExtendedEllipsoidTest.java
index a8fe639d..cefc05a7 100644
--- a/src/test/java/org/orekit/rugged/core/ExtendedEllipsoidTest.java
+++ b/src/test/java/org/orekit/rugged/core/ExtendedEllipsoidTest.java
@@ -226,11 +226,13 @@ public class ExtendedEllipsoidTest {
         Vector3D converted = ellipsoid.convertLos(gp, los);
         Line line = new Line(p, new Vector3D(1.0, p, 1000, los), 1.0e-10);
 
-        for (double delta = 0; delta < 100.0; delta += 0.1) {
+        for (double delta = 0.1; delta < 100.0; delta += 0.1) {
             GeodeticPoint shifted = new GeodeticPoint(gp.getLatitude()  + delta * converted.getY(),
                                                       gp.getLongitude() + delta * converted.getX(),
                                                       gp.getAltitude()  + delta * converted.getZ());
-            Assert.assertEquals(0.0, line.distance(ellipsoid.transform(shifted)), 1.0e-3);
+            Vector3D converted2 = ellipsoid.convertLos(p, ellipsoid.transform(shifted));
+            Assert.assertEquals(0.0, Vector3D.distance(converted, converted2), 3.0e-5 * converted.getNorm());
+            Assert.assertEquals(0.0, line.distance(ellipsoid.transform(shifted)), 8.0e-4);
         }
 
     }
-- 
GitLab