From 3aae8e8675f476a9c10a6ba4126c0923ffba9b8b Mon Sep 17 00:00:00 2001
From: Luc Maisonobe <luc@orekit.org>
Date: Mon, 5 May 2014 15:36:47 +0200
Subject: [PATCH] Ensure sensor mean plane normal has a deterministic
 orientation.

---
 .../java/org/orekit/rugged/core/Sensor.java   | 20 +++++++++++++++----
 .../org/orekit/rugged/core/SensorTest.java    |  8 ++++----
 2 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/orekit/rugged/core/Sensor.java b/src/main/java/org/orekit/rugged/core/Sensor.java
index 05c75779..56062e2c 100644
--- a/src/main/java/org/orekit/rugged/core/Sensor.java
+++ b/src/main/java/org/orekit/rugged/core/Sensor.java
@@ -114,7 +114,14 @@ public class Sensor {
         // extract the left singular vector corresponding to least singular value
         // (i.e. last vector since Apache Commons Math returns the values
         //  in non-increasing order)
-        normal = new Vector3D(svd.getU().getColumn(2)).normalize();
+        final Vector3D singularVector = new Vector3D(svd.getU().getColumn(2)).normalize();
+
+        // check rotation order
+        if (Vector3D.dotProduct(singularVector, Vector3D.crossProduct(los.get(0), los.get(los.size() - 1))) >= 0) {
+            normal = singularVector;
+        } else {
+            normal = singularVector.negate();
+        }
 
     }
 
@@ -165,16 +172,21 @@ public class Sensor {
     }
 
     /** Get the mean plane normal.
+     * <p>
+     * The normal is oriented such traversing pixels in increasing indices
+     * order corresponds is consistent with trigonometric order (i.e.
+     * counterclockwise).
+     * </p>
      * @return mean plane normal
      */
     public Vector3D getMeanPlaneNormal() {
         return normal;
     }
 
-    /** Get the mean plane reference point.
-     * @return mean plane reference point
+    /** Get the sensor reference point.
+     * @return reference point
      */
-    public Vector3D getMeanPlaneReferencePoint() {
+    public Vector3D getReferencePoint() {
         return referencePoint;
     }
 
diff --git a/src/test/java/org/orekit/rugged/core/SensorTest.java b/src/test/java/org/orekit/rugged/core/SensorTest.java
index 748aedbb..2d22421a 100644
--- a/src/test/java/org/orekit/rugged/core/SensorTest.java
+++ b/src/test/java/org/orekit/rugged/core/SensorTest.java
@@ -52,8 +52,8 @@ public class SensorTest {
 
         Assert.assertEquals("perfect line", sensor.getName());
         Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
-        Assert.assertEquals(0.0, Vector3D.dotProduct(normal, center.subtract(sensor.getMeanPlaneReferencePoint())), 1.0e-15);
-        Assert.assertEquals(0.0, FastMath.sin(Vector3D.angle(normal, sensor.getMeanPlaneNormal())), 1.0e-15);
+        Assert.assertEquals(0.0, Vector3D.dotProduct(normal, center.subtract(sensor.getReferencePoint())), 1.0e-15);
+        Assert.assertEquals(0.0, Vector3D.angle(normal, sensor.getMeanPlaneNormal()), 1.0e-15);
 
     }
 
@@ -85,8 +85,8 @@ public class SensorTest {
 
         Assert.assertEquals("noisy line", sensor.getName());
         Assert.assertEquals(AbsoluteDate.J2000_EPOCH, sensor.getDate(0.0));
-        Assert.assertEquals(0.0, Vector3D.dotProduct(normal, center.subtract(sensor.getMeanPlaneReferencePoint())), 1.0e-5);
-        Assert.assertEquals(0.0, FastMath.sin(Vector3D.angle(normal, sensor.getMeanPlaneNormal())), 3.0e-7);
+        Assert.assertEquals(0.0, Vector3D.dotProduct(normal, center.subtract(sensor.getReferencePoint())), 1.0e-5);
+        Assert.assertEquals(0.0, Vector3D.angle(normal, sensor.getMeanPlaneNormal()), 3.0e-7);
 
     }
 
-- 
GitLab