From 3d91cec19c66b8005f602fab25e695060c526523 Mon Sep 17 00:00:00 2001
From: Luc Maisonobe <luc@orekit.org>
Date: Sat, 15 Mar 2014 18:24:52 +0100
Subject: [PATCH] Added getMergingRow and getMergingColumn methods.

These methods are essential to identify where to split the line-of-sight
in the Duvenhage algorithm, when going from one level in the min/max
kd-tree to the next level.
---
 .../rugged/core/duvenhage/MinMaxTreeTile.java | 26 ++++++++++
 .../core/duvenhage/MinMaxTreeTileTest.java    | 48 +++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
index 0205e3f7..171c457e 100644
--- a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
+++ b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
@@ -155,6 +155,32 @@ public class MinMaxTreeTile extends SimpleTile {
 
     }
 
+    /** Get the row at which the two sub-tiles of level+1 were merged to give current level sub-tile.
+     * @param i row index of pixel in current sub-tile
+     * @param level tree level
+     * @return index of row at which higher level sub-tiles were merged
+     * (beware that this may be {@link #getLatitudeRows()} or more if the last row was not
+     * really merged because level+1 sub-tile was not complete)
+     */
+    public int getMergingRow(final int i, final int level) {
+        final int k        = start.length - level;
+        final int rowShift = k / 2;
+        return (i & (-1 << rowShift)) + (1 << (rowShift - 1));
+    }
+
+    /** Get the column at which the two sub-tiles of level+1 were merged to give current level sub-tile.
+     * @param j column index of pixel in current sub-tile
+     * @param level tree level
+     * @return index of column at which higher level sub-tiles were merged
+     * (beware that this may be {@link #getLongitudeColumns()} or more if the last columns was not
+     * really merged because level+1 sub-tile was not complete)
+     */
+    public int getMergingColumn(final int j, final int level) {
+        final int k        = start.length - level;
+        final int colShift = (k + 1) / 2;
+        return (j & (-1 << colShift)) + (1 << (colShift - 1));
+    }
+
     /** Check if the merging operation between level and level+1 is a column merging.
      * @param level level to check
      * @return true if the merging operation between level and level+1 is a column
diff --git a/rugged-core/src/test/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java b/rugged-core/src/test/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
index b22f7f07..abfe7550 100644
--- a/rugged-core/src/test/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
+++ b/rugged-core/src/test/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
@@ -186,6 +186,54 @@ public class MinMaxTreeTileTest {
         }
     }
 
+    @Test
+    public void testMergingRow() throws RuggedException {
+        for (int nbRows = 1; nbRows < 25; nbRows++) {
+            for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
+
+                MinMaxTreeTile tile = createTile(nbRows, nbColumns);
+
+                for (int i = 0; i < nbRows; i++) {
+                    for (int level = 0; level < tile.getLevels(); ++level) {
+                        int iMerge = tile.getMergingRow(i, level);
+                        if (iMerge < tile.getLatitudeRows()) {
+                            int levelUp = tile.isColumnMerging(level) ? level + 2 : level + 1;
+                            if (levelUp < tile.getLevels()) {
+                                int[] neighbors1 = neighbors(iMerge - 1, 0, nbRows, nbColumns, tile.getLevels() - levelUp);
+                                int[] neighbors2 = neighbors(iMerge,     0, nbRows, nbColumns, tile.getLevels() - levelUp);
+                                Assert.assertEquals(neighbors1[1], neighbors2[0]);
+                           }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testMergingColumn() throws RuggedException {
+        for (int nbRows = 1; nbRows < 25; nbRows++) {
+            for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
+
+                MinMaxTreeTile tile = createTile(nbRows, nbColumns);
+
+                for (int j = 0; j < nbColumns; j++) {
+                    for (int level = 0; level < tile.getLevels(); ++level) {
+                        int jMerge = tile.getMergingColumn(j, level);
+                        if (jMerge < tile.getLongitudeColumns()) {
+                            int levelUp = tile.isColumnMerging(level) ? level + 1 : level + 2;
+                            if (levelUp < tile.getLevels()) {
+                                int[] neighbors1 = neighbors(0, jMerge - 1, nbRows, nbColumns, tile.getLevels() - levelUp);
+                                int[] neighbors2 = neighbors(0, jMerge,     nbRows, nbColumns, tile.getLevels() - levelUp);
+                                Assert.assertEquals(neighbors1[3], neighbors2[2]);
+                           }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private int[] neighbors(int row, int column, int nbRows, int nbColumns, int stages) {
 
         // poor man identification of neighbors cells merged together with specified cell
-- 
GitLab