From f674a01d35be3bbfe765402bf6bc104ec91b366f Mon Sep 17 00:00:00 2001
From: Maria Kocurekova <xkocure1@fi.muni.cz>
Date: Tue, 1 Dec 2020 21:01:13 +0100
Subject: [PATCH] Add Comparators to KdTree class...

---
 .../fidentis/analyst/mesh/KdTree/KdNode.java  |   1 -
 .../analyst/mesh/KdTree/KdTreeImpl.java       | 146 ++++++++----------
 .../analyst/mesh/KdTree/kdTreeTest.java}      |  44 +++++-
 3 files changed, 102 insertions(+), 89 deletions(-)
 rename MeshModel/src/{main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java => test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java} (71%)

diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
index f0c30dd5..879b7277 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdNode.java
@@ -5,7 +5,6 @@ import cz.fidentis.analyst.mesh.core.MeshPoint;
 
 public class KdNode {
     private int index;
-    // represents index of vertices in the class MashFacetImpl in the attribute vertices
     private final int depth;
     private MeshPoint id;
 
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
index 43e339e5..d287b1d3 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImpl.java
@@ -3,42 +3,75 @@ package cz.fidentis.analyst.mesh.KdTree;
 import cz.fidentis.analyst.mesh.core.MeshPoint;
 
 
-import javax.vecmath.Vector3d;
+
 import java.util.*;
 
 public class KdTreeImpl {
     private final KdNode root;
-    private final List<MeshPoint> points;
-
-    //private Map<MeshPoint, Integer> pointsWithIndex = new HashMap<>();
 
     private final static int X_AXIS = 0;
     private final static int Y_AXIS = 1;
     private final static int Z_AXIS = 2;
 
+    private static class Pair {
+        private MeshPoint p;
+        private Integer index;
 
+        public Pair(MeshPoint p, int index) {
+            this.p = p;
+            this. index = index;
+        }
 
+        public MeshPoint getP() {
+            return p;
+        }
 
-    public KdTreeImpl(List<MeshPoint> points) {
-        if(points == null || points.isEmpty()){
-            this.root = null;
-            this.points = null;
-            return;
+        public Integer getIndex() {
+            return index;
         }
+    }
 
-        this.points = points;
+/**
+    private static final Comparator<Pair> X_COMPARATOR = (o1, o2) -> {
+        if (o1.getP().getPosition().x < o2.getP().getPosition().x)
+            return -1;
+        if (o1.getP().getPosition().x > o2.getP().getPosition().x)
+            return 1;
+        return 0;
+    };
 
-        List<Integer> pointsCopy = new ArrayList<>(points.size());
-        for(int i = 0; i < points.size(); i++){
-            pointsCopy.add(i);
-        }
+    private static final Comparator<Pair> Y_COMPARATOR = (o1, o2) -> {
+        if (o1.getP().getPosition().y < o2.getP().getPosition().y)
+            return -1;
+        if (o1.getP().getPosition().y > o2.getP().getPosition().y)
+            return 1;
+        return 0;
+    };
+
+    private static final Comparator<Pair> Z_COMPARATOR = (o1, o2) -> {
+        if (o1.getP().getPosition().z < o2.getP().getPosition().z)
+            return -1;
+        if (o1.getP().getPosition().z > o2.getP().getPosition().z)
+            return 1;
+        return 0;
+    };**/
 
-        pointsCopy = deleteDuplicates(points); //(pointsCopy,
 
-        List<Integer> sortedByX = sortPoints(pointsCopy, X_AXIS, points);
-        List<Integer> sortedByY = sortPoints(pointsCopy, Y_AXIS, points);
-        List<Integer> sortedByZ = sortPoints(pointsCopy, Z_AXIS, points);
+    private static final Comparator<Pair> X_COMPARATOR = Comparator.comparingDouble(o -> o.getP().getPosition().x);
 
+    private static final Comparator<Pair> Y_COMPARATOR = Comparator.comparingDouble(o -> o.getP().getPosition().y);
+
+    private static final Comparator<Pair> Z_COMPARATOR = Comparator.comparingDouble(o -> o.getP().getPosition().z);
+
+    public KdTreeImpl(List<MeshPoint> points) {
+        if(points == null || points.isEmpty()){
+            this.root = null;
+            return;
+        }
+
+        List<Integer> sortedByX = sortPoints( X_AXIS, points);
+        List<Integer> sortedByY = sortPoints( Y_AXIS, points);
+        List<Integer> sortedByZ = sortPoints( Z_AXIS, points);
 
         root = buildTree(null, sortedByX, sortedByY, sortedByZ, 0, points);
 
@@ -56,77 +89,28 @@ public class KdTreeImpl {
         return false;
     }
 
-    private List<Integer> merge(List<Integer> left, List<Integer> right, int level, List<MeshPoint> points){
-        List<Integer> mergedList = new ArrayList<>(left.size() + right.size());
 
-        int fromLeft = 0;
-        int fromRight = 0;
+    private List<Integer> sortPoints(/*List<Integer> points,*/ int level, List<MeshPoint> p){
+        List<Integer> sortedListIndex = new ArrayList<>(p.size());
+        List<Pair> sortedListPairs = new ArrayList<>(p.size());
 
-        while(fromLeft < left.size() || fromRight < right.size()){
-            if(fromLeft < left.size() && fromRight < right.size()){
-                if(comparePointsOnLevel(points.get(left.get(fromLeft)), points.get(right.get(fromRight)), level)){
-                    mergedList.add(left.get(fromLeft));
-                    fromLeft++;
-                }else{
-                    mergedList.add(right.get(fromRight));
-                    fromRight++;
-                }
-            }else if(fromLeft < left.size()){
-                mergedList.add(left.get(fromLeft));
-                fromLeft++;
-            }else if(fromRight < right.size()){
-                mergedList.add(right.get(fromRight));
-                fromRight++;
-            }
+        for (int i = 0; i < p.size(); i++ ) {
+            sortedListPairs.add(new Pair(p.get(i), i));
         }
 
-        return mergedList;
-    }
-
-    private List<Integer> mergeSort(List<Integer> points, int level, List<MeshPoint> p){
-        if(points.size() <= 1){
-            return points;
+        if(level % 3 == 0){
+            sortedListPairs.sort(X_COMPARATOR);
+        }else if(level % 3 == 1){
+            sortedListPairs.sort(Y_COMPARATOR);
+        }else if(level % 3 == 2){
+            sortedListPairs.sort(Z_COMPARATOR);
         }
 
-        List<Integer> left;
-        List<Integer> right;
-
-        int mid = (points.size()/2);
-
-        left = points.subList(0, mid);
-        right = points.subList(mid, points.size());
-
-
-        left = mergeSort(left, level, p);
-        right = mergeSort(right, level, p);
-
-        return merge(left, right, level, p);
-    }
-
-    private List<Integer> sortPoints(List<Integer> points, int level, List<MeshPoint> p){
-        List<Integer> sortedList = new ArrayList<>(points.size());
-
-        sortedList.addAll(points);
-
-        sortedList = mergeSort(sortedList,level, p);
-
-        return sortedList;
-
-    }
-
-
-    private List<Integer> deleteDuplicates(List<MeshPoint> points){ // List<Integer> list
-        List<Vector3d> noDuplicates = new ArrayList<>();
-        List<Integer> noDupIndex = new ArrayList<>();
-
-        for(int i = 0; i < points.size(); i++){
-            if(!noDuplicates.contains(points.get(i).getPosition())){
-                noDuplicates.add(points.get(i).getPosition());
-                noDupIndex.add(i);
-            }
+        for(Pair pair : sortedListPairs) {
+            sortedListIndex.add(pair.getIndex());
         }
+        return sortedListIndex;
 
-        return noDupIndex;
     }
 
 
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
similarity index 71%
rename from MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java
rename to MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
index f6cf8f5e..4d4a8c11 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/KdTree/KdTreeImplTests.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/KdTree/kdTreeTest.java
@@ -1,21 +1,25 @@
 package cz.fidentis.analyst.mesh.KdTree;
-
 import cz.fidentis.analyst.mesh.core.MeshPoint;
 import cz.fidentis.analyst.mesh.core.MeshPointImpl;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 import javax.vecmath.Vector3d;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+
 
+public class kdTreeTest {
 
-public class KdTreeImplTests {
     private Vector3d position = new Vector3d(0.1f, 0.5f, 0.7f);
     private Vector3d normalAndTextCoord = new Vector3d(0,0,0);
 
+
     @Test
     public void testPut(){
         MeshPoint p = new MeshPointImpl(position,normalAndTextCoord,normalAndTextCoord);
@@ -65,7 +69,7 @@ public class KdTreeImplTests {
     @Test
     public void testFindClosestAlreadyIn(){
         List<MeshPoint> points = new LinkedList<>();
-         Vector3d positionOfPoints;
+        Vector3d positionOfPoints;
 
         for(int i = 0; i < 10; i++){
             positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
@@ -79,7 +83,7 @@ public class KdTreeImplTests {
         MeshPoint found = tree.nearestNeighbour(p);
 
         assertEquals(found, p);
-        assertTrue(distancePoints(found, p) == 0.0f);
+        assertEquals(0.0f, distancePoints(found, p));
     }
 
     @Test
@@ -100,7 +104,33 @@ public class KdTreeImplTests {
         MeshPoint seq = findClosestSequential(points, p);
 
         assertEquals(found, seq);
-        assertTrue(distancePoints(found, p) == distancePoints(seq, p));
+        assertEquals(distancePoints(found, p), distancePoints(seq, p));
+    }
+
+    @Test
+    public void testIndexFound(){
+        List<MeshPoint> points = new LinkedList<>();
+        Vector3d positionOfPoints;
+
+        for(int i = 5; i < 10; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+        for(int i = 0; i < 5; i++){
+            positionOfPoints = new Vector3d(0.1f * i, 0.5f * i, 0.7f * i);
+            points.add(new MeshPointImpl(positionOfPoints, normalAndTextCoord, normalAndTextCoord));
+        }
+
+        KdTreeImpl tree = new KdTreeImpl(points);
+        Random r = new Random();
+
+        MeshPoint p = points.get(r.nextInt(points.size()));
+        int found = tree.nearestNeighbourIndex(p);
+
+        assertEquals(points.get(found), p);
+        assertEquals(0.0f, distancePoints(points.get(found), p));
     }
 
 }
+
+
-- 
GitLab