diff --git a/Comparison/src/main/java/cz/fidentis/analyst/EfficiencyTests.java b/Comparison/src/main/java/cz/fidentis/analyst/EfficiencyTests.java
index 27ecd8c2aa34b11718a24ed53fc4a7a56325ab3f..794fbe1a94b36c7bfe1d1862f47c20edabf362ac 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/EfficiencyTests.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/EfficiencyTests.java
@@ -57,13 +57,13 @@ public class EfficiencyTests {
         
         System.out.println();
         System.out.println("Hausdorff distance sequentially:");
-        testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT_ABSOLUTE, false, false, false), printDetails);
+        testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT_DISTANCE_ONLY, false, false, false), printDetails);
         testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT, relativeDist, false, false), printDetails);
         testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_TRIANGLE_APPROXIMATE, relativeDist, false, false), printDetails);
 
         System.out.println();
-        System.out.println("Hausdorff distance consurrently:");
-        testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT_ABSOLUTE, false, false, true), printDetails);
+        System.out.println("Hausdorff distance concurrently:");
+        testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT_DISTANCE_ONLY, false, false, true), printDetails);
         testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_POINT, relativeDist, false, true), printDetails);
         testAndPrint(face1, new HausdorffDistance(face2.getMeshModel(), Strategy.POINT_TO_TRIANGLE_APPROXIMATE, relativeDist, false, true), printDetails);
     }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/KdTreeDistance.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/KdTreeDistance.java
index 5218f3cdda44028a7d1736a59a3850d34a6e9d7e..6d2746d211d24f518aaa68646a04f06e6a1e0f8e 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/KdTreeDistance.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/KdTreeDistance.java
@@ -1,6 +1,5 @@
 package cz.fidentis.analyst.visitors.kdtree;
 
-import cz.fidentis.analyst.kdtree.KdNode;
 import cz.fidentis.analyst.kdtree.KdTree;
 import cz.fidentis.analyst.kdtree.KdTreeVisitor;
 import cz.fidentis.analyst.visitors.Distance;
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistance.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistance.java
index 6d2664044e189b7ea649eaa8de5ac7bf512d1640..0e32da5d667fa74a9cdea12d7a3c9da5f04a189e 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistance.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistance.java
@@ -18,48 +18,47 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import javax.vecmath.Vector3d;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import javax.vecmath.Vector3d;
-
 /**
  * Visitor for Hausdorff distance. 
  * This visitor is instantiated with a single k-d tree (either given as the input
  * parameter, or automatically created from the triangular mesh). 
- * When applied to other mesh facets, it computes Huasdorff distance from them to 
+ * When applied to other mesh facets, it computes Hausdorff distance from them to 
  * the instantiated k-d tree.
  * <p>
  * This visitor is thread-safe.
  * </p>
  * <p>
- * The distance is computer aither as absolute or relative. Abosolute
+ * The distance is computer either as absolute or relative. Absolute
  * represents Euclidean distance (all numbers are positive). On the contrary, 
  * relative distance considers orientation of the visited mesh (determined by its normal vectors)
  * and produces positive or negative distances depending on whether the primary
  * mesh is "in front of" or "behind" the given vertex.
  * </p>
  * <p>
- * Comparison of methods' efficiency performed with scans of two human faces on 
+ * Comparison of methods efficiency performed with scans of two human faces on 
  * Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz, 8 CPU cores.
  * </p>
  * <p>
  * Hausdorff distance sequentially:
  * <table>
- * <tr><td>2076 msec</td><td>POINT_TO_POINT_ABSOLUTE</td></tr>
- * <tr><td>3991 msec</td><td>POINT_TO_POINT</td></tr>
- * <tr><td>5528 msec</td><td>POINT_TO_TRIANGLE_APPROXIMATE</td></tr>
+ * <tr><td>2443 msec</td><td>OINT_TO_POINT_DISTANCE_ONLY</td></tr>
+ * <tr><td>2495 msec</td><td>POINT_TO_POINT</td></tr>
+ * <tr><td>3430 msec</td><td>POINT_TO_TRIANGLE_APPROXIMATE</td></tr>
  * </table>
  * </p>
  * <p>
- * Hausdorff distance consurrently:
+ * Hausdorff distance concurrently:
  * <table>
- * <tr><td>1583 msec</td><td>POINT_TO_POINT_ABSOLUTE</td></tr>
- * <tr><td>2399 msec</td><td>POINT_TO_POINT</td></tr>
- * <tr><td>2745 msec</td><td>POINT_TO_TRIANGLE_APPROXIMATE</td></tr>
+ * <tr><td>1782 msec</td><td>OINT_TO_POINT_DISTANCE_ONLY</td></tr>
+ * <tr><td>2248 msec</td><td>POINT_TO_POINT</td></tr>
+ * <tr><td>2574 msec</td><td>POINT_TO_TRIANGLE_APPROXIMATE</td></tr>
  * </table>
  * </p>
  * 
@@ -73,41 +72,53 @@ public class HausdorffDistance extends MeshVisitor  {
      * @author Radek Oslejsek
      */
     public enum Strategy {
+        
         /**
-         * The fastest algorithm. Computes abolute distance between mesh vertices.
-         * Relative distance is not supported.
+         * The fastest algorithm. Computes absolute distance between mesh vertices.
+         * Relative distance is not supported, no closest points are returned.
          */
-        POINT_TO_POINT_ABSOLUTE,
+        POINT_TO_POINT_DISTANCE_ONLY,
         
         /**
-         * A bit slower point-to-point algorithm. 
-         * But supports both relative and absolute distances.
-         * However, for relative distance can produce noise. If there are multiple 
-         * closest points to the given vertex, then 
-         * {@code Double.POSITIVE_INFINITY} value is set as the distance.
-         * If this situation happens with human faces, then we consider this part
-         * of the face as noisy anyway.
+         * A bit slower point-to-point algorithm. But supports both relative and absolute distances.
+         * Moreover, the closest points are returned.
+         * <p>
+         * This algorithm can can produce "noise". If there are multiple closest points 
+         * at the primary mesh, then it is not possible to choose which of them is correct (better). 
+         * Therefore, the {@code Double.POSITIVE_INFINITY} value is set as the distance for this vertices.
+         * If this situation happens with human faces, we would consider this part
+         * of the face as noisy anyway, trying to avoid these parts from further processing.
+         * </p>
          */
         POINT_TO_POINT,
         
         /**
-         * The fast point-to-triangle distance strategy, which more precise
-         * than point-to-point strategies. 
-         * Supports both relative and absolute distances.
-         * However, the algorithm is not geometrically correct. 
-         * Can produce noise (does not found the really closests triangle) on wrinkly sufaces. 
-         * Nevertheless, we aim to omit such noisy parts of human face from analysis
-         * rather than dealing with this situation.
+         * The fast point-to-triangle distance strategy. Produces more precise results
+         * than the {@code POINT_TO_POINT} strategy, but is a bit slower.
+         * <p>
+         * The algorithm supports both relative and absolute distances.
+         * But is not geometrically correct. Can produce "noise"
+         * in the sense that it may not found the really closest triangle on "wrinkly" surfaces. 
+         * If this situation happens with human faces, we would consider this part
+         * of the face as noisy anyway, trying to avoid these parts from further processing.
+         * </p>
          */
         POINT_TO_TRIANGLE_APPROXIMATE
     }
     
     /**
-     * Result. 
+     * Hausdorff distance for all inspected meshes.
      * Key = visited mesh facets. 
-     * Vvalue = Hausdorff distance of each vertex of the visited facet to the source facet.
+     * Value = Hausdorff distance of each vertex of the visited facet to the source facet.
      */
     private final Map<MeshFacet, List<Double>> distances = new HashMap<>();
+
+    /**
+     * The closest points for all inspected meshes (empty for the {@code POINT_TO_POINT_ABSOLUTE} strategy
+     * Key = visited mesh facets.
+     * Value = The nearest point of each vertex of the visited facet to the source facet.
+     */
+    private final Map<MeshFacet, List<Vector3d>> nearestPoints = new HashMap<>();
     
     private final Strategy strategy;
     
@@ -116,7 +127,7 @@ public class HausdorffDistance extends MeshVisitor  {
     private final boolean parallel;
     
     /**
-     * The source triangular mesh (set of mesh facets) stred in k-d tree.
+     * The source triangular mesh (set of mesh facets) stored in k-d tree.
      */
     private final KdTree kdTree;
     
@@ -130,7 +141,7 @@ public class HausdorffDistance extends MeshVisitor  {
      * i.e., we can get negative distances.
      * @param asynchronous If {@code true}, then the inspection of mesh facets is asynchronous (and possibly concurrent).
      * @param parallel If {@code true}, then the algorithm runs concurrently utilizing all CPU cores
-     * @throws IllegalArgumentException if some parametr is wrong
+     * @throws IllegalArgumentException if some parameter is wrong
      */
     public HausdorffDistance(Set<MeshFacet> mainFacets, Strategy strategy, boolean relativeDistance, boolean asynchronous, boolean parallel) {
         super(asynchronous);
@@ -140,7 +151,7 @@ public class HausdorffDistance extends MeshVisitor  {
         if (mainFacets == null) {
             throw new IllegalArgumentException("mainFacets");
         }
-        if (strategy == Strategy.POINT_TO_POINT_ABSOLUTE && relativeDistance) {
+        if (strategy == Strategy.POINT_TO_POINT_DISTANCE_ONLY && relativeDistance) {
             throw new IllegalArgumentException("Point-to-point strategy cannot be used with relative distance");
         }
         this.kdTree = new KdTree(new ArrayList<>(mainFacets));
@@ -156,7 +167,7 @@ public class HausdorffDistance extends MeshVisitor  {
      * i.e., we can get negative distances.
      * @param asynchronous If {@code true}, then the inspection of mesh facets is asynchronous (and possibly concurrent).
      * @param parallel If {@code true}, then the algorithm runs concurrently utilizing all CPU cores
-     * @throws IllegalArgumentException if some parametr is wrong
+     * @throws IllegalArgumentException if some parameter is wrong
      */
     public HausdorffDistance(MeshFacet mainFacet, Strategy strategy, boolean relativeDistance, boolean asynchronous, boolean parallel) {
         this(new HashSet<>(Collections.singleton(mainFacet)), strategy, relativeDistance, asynchronous, parallel);
@@ -176,7 +187,7 @@ public class HausdorffDistance extends MeshVisitor  {
      * i.e., we can get negative distances.
      * @param asynchronous If {@code true}, then the inspection of mesh facets is asynchronous (and possibly concurrent).
      * @param parallel If {@code true}, then the algorithm runs concurrently utilizing all CPU cores
-     * @throws IllegalArgumentException if some parametr is wrong
+     * @throws IllegalArgumentException if some parameter is wrong
      */
     public HausdorffDistance(MeshModel mainModel, Strategy strategy, boolean relativeDistance, boolean asynchronous, boolean parallel) {
         this(new HashSet<>(mainModel.getFacets()), strategy, relativeDistance, asynchronous, parallel);
@@ -195,7 +206,7 @@ public class HausdorffDistance extends MeshVisitor  {
      * i.e., we can get negative distances.
      * @param asynchronous If {@code true}, then the inspection of mesh facets is asynchronous (and possibly concurrent).
      * @param parallel If {@code true}, then the algorithm runs concurrently utilizing all CPU cores
-     * @throws IllegalArgumentException if some parametr is wrong
+     * @throws IllegalArgumentException if some parameter is wrong
      */
     public HausdorffDistance(KdTree mainKdTree, Strategy strategy, boolean relativeDistance, boolean asynchronous, boolean parallel) {
         super(asynchronous);
@@ -205,7 +216,7 @@ public class HausdorffDistance extends MeshVisitor  {
         if (mainKdTree == null) {
             throw new IllegalArgumentException("mainKdTree");
         }
-        if (strategy == Strategy.POINT_TO_POINT_ABSOLUTE && relativeDistance) {
+        if (strategy == Strategy.POINT_TO_POINT_DISTANCE_ONLY && relativeDistance) {
             throw new IllegalArgumentException("Point-to-point strategy cannot be used with relative distance");
         }
         this.kdTree = mainKdTree;
@@ -213,9 +224,9 @@ public class HausdorffDistance extends MeshVisitor  {
     
     /**
      * Returns Hausdorff distance of mesh facets to the source mesh facets. 
-     * Keys in the map contain mesh facets that were measued with the 
+     * Keys in the map contain mesh facets that were measured with the 
      * source facets. For each measured facet, a list of distances to the source 
-     * facets is stored. The order od distances corresopnds to the order of vertices
+     * facets is stored. The order of distances corresponds to the order of vertices
      * in the measured facet, i.e., the i-th value is the distance of the i-th vertex
      * of the measured facet.
      * 
@@ -224,7 +235,20 @@ public class HausdorffDistance extends MeshVisitor  {
     public Map<MeshFacet, List<Double>> getDistances() {
         return Collections.unmodifiableMap(distances);
     }
-    
+
+    /**
+     * Returns the nearest points of mesh facets to the source mesh facets.
+     * Keys in the map contain mesh facets that were measured with the
+     * source facets. For each measured facet, a list of the nearest points to the source
+     * facets is stored. The order of  points corresponds to the order of vertices
+     * in the measured facet, i.e., the i-th point is the nearest point of the i-th vertex
+     * of the measured facet.
+     *
+     * @return The nearest points for all points of all measured facets
+     */
+    public Map<MeshFacet, List<Vector3d>> getNearestPoints() {
+        return Collections.unmodifiableMap(nearestPoints);
+    }
     /**
      * Returns {@code true} if the distance was computed as relative 
      * (with possibly negative values). 
@@ -258,13 +282,19 @@ public class HausdorffDistance extends MeshVisitor  {
     
     @Override
     protected void visitMeshFacet(MeshFacet comparedFacet) {
-        if (distances.containsKey(comparedFacet)) {
-            return; // multiply visited facet
-        }
-        
         final List<Double> distList = new ArrayList<>();
-        distances.put(comparedFacet, distList);
+        final List<Vector3d> nearestPointsList = new ArrayList<>();
         
+        synchronized (this) {
+            if (distances.containsKey(comparedFacet)) {
+                return; // skip repeatedly visited facets
+            }
+            distances.put(comparedFacet, distList);
+            if (getStrategy() != Strategy.POINT_TO_POINT_DISTANCE_ONLY) {
+                nearestPoints.put(comparedFacet, nearestPointsList);
+            }
+        }
+
         final List<MeshPoint> vertices = comparedFacet.getVertices();
         final List<Future<KdTreeVisitor>> results = new ArrayList<>(vertices.size());
         
@@ -277,7 +307,7 @@ public class HausdorffDistance extends MeshVisitor  {
             if (inParallel()) { // fork and continue
                 results.add(executor.submit(visitor));
             } else { // process distance results immediately
-                addDistanceToPoint(visitor, vertices.get(i), distList);
+                updateResults(visitor, vertices.get(i), comparedFacet);
             }
         }
             
@@ -289,7 +319,7 @@ public class HausdorffDistance extends MeshVisitor  {
                 int i = 0;
                 for (Future<KdTreeVisitor> res: results) {
                     final KdTreeVisitor visitor = (KdTreeVisitor) res.get(); // waits until all computations are finished
-                    addDistanceToPoint(visitor, vertices.get(i), distList);
+                    updateResults(visitor, vertices.get(i), comparedFacet);
                     i++;
                 }
             } catch (final InterruptedException | ExecutionException ex) {
@@ -300,7 +330,7 @@ public class HausdorffDistance extends MeshVisitor  {
     
     protected KdTreeVisitor instantiateVisitor(Vector3d inspectedPoint) {
         switch (getStrategy()) {
-            case POINT_TO_POINT_ABSOLUTE:
+            case POINT_TO_POINT_DISTANCE_ONLY:
                 return new KdTreeDistance(inspectedPoint, inParallel());
             case POINT_TO_POINT:
                 return new KdTreeDistanceToVertices(inspectedPoint, inParallel());
@@ -309,16 +339,36 @@ public class HausdorffDistance extends MeshVisitor  {
                 return new KdTreeApproxDistanceToTriangles(inspectedPoint, inParallel());
         }
     }
-    
-    protected void addDistanceToPoint(KdTreeVisitor vis, MeshPoint point, List<Double> pointDistances) {
-        if (relativeDist && vis instanceof DistanceWithNearestPoints) {
-            double relDist = checkDist((DistanceWithNearestPoints)vis, point);
-            pointDistances.add(relDist);
-        } else {
-            pointDistances.add(((Distance) vis).getDistance());
+
+    protected void updateResults(KdTreeVisitor vis, MeshPoint point, MeshFacet facet) {
+        Vector3d closestV = null;
+        
+        if (vis instanceof DistanceWithNearestPoints) { // We have nearest points
+            closestV = this.getClosestVertex((DistanceWithNearestPoints)vis);
+            
+            if (closestV == null) { // unable to get a single closest point
+                distances.get(facet).add(Double.POSITIVE_INFINITY);
+                nearestPoints.get(facet).add(null);
+                return;
+            }
+        }
+
+        double dist = ((Distance) vis).getDistance();
+        int sign = 1;
+
+        if (relativeDist) { // compute sign for relative distance
+            Vector3d aux = new Vector3d(closestV);
+            aux.sub(point.getPosition());
+            sign = (int) Math.signum(aux.dot(point.getNormal()));
+        } 
+        
+        distances.get(facet).add(sign * dist);
+        if (nearestPoints.containsKey(facet)) { // only strategies with the closest points are stored in the map
+            nearestPoints.get(facet).add(closestV); 
         }
     }
     
+    /*
     protected double checkDist(DistanceWithNearestPoints vis, MeshPoint myPoint) {
         double dist = vis.getDistance();
         
@@ -345,4 +395,24 @@ public class HausdorffDistance extends MeshVisitor  {
         
         return sign * dist;
     }
+    */
+    
+    /**
+     * @param vis visitor
+     * @return the only one existing closest vertex or {@code null}
+     */
+    protected Vector3d getClosestVertex(DistanceWithNearestPoints vis) {
+        if (vis.getNearestPoints().size() != 1) { 
+            return null; // somethig is wrong because there should be only my inspected facet
+        }
+        
+        MeshFacet myInspectedFacet = vis.getNearestPoints().keySet().stream().findFirst().get();
+        
+        if (vis.getNearestPoints().get(myInspectedFacet).size() != 1) {
+            return null; // multiple closest points; we don't know wich one to choose
+        }
+        
+        // return the only one closest vertex
+        return vis.getNearestPoints().get(myInspectedFacet).get(0);
+    }
 }
diff --git a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistanceTest.java b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistanceTest.java
index 44db008a0d3e185e8be5c88fe6020e2e7ffff560..14839231266fe6b716e371678316ff9d3590174e 100644
--- a/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistanceTest.java
+++ b/Comparison/src/test/java/cz/fidentis/analyst/visitors/mesh/HausdorffDistanceTest.java
@@ -1,17 +1,15 @@
 package cz.fidentis.analyst.visitors.mesh;
 
-import cz.fidentis.analyst.mesh.core.CornerTableRow;
-import cz.fidentis.analyst.mesh.core.MeshFacet;
-import cz.fidentis.analyst.mesh.core.MeshFacetImpl;
-import cz.fidentis.analyst.mesh.core.MeshModel;
-import cz.fidentis.analyst.mesh.core.MeshPointImpl;
+import cz.fidentis.analyst.mesh.core.*;
 import cz.fidentis.analyst.visitors.mesh.HausdorffDistance.Strategy;
+import org.junit.jupiter.api.Test;
+
+import javax.vecmath.Vector3d;
 import java.util.List;
 import java.util.Map;
-import javax.vecmath.Vector3d;
+
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import org.junit.jupiter.api.Test;
 
 public class HausdorffDistanceTest {
 
@@ -46,6 +44,24 @@ public class HausdorffDistanceTest {
             assertEquals(expectedDist, results.get(i));
         }
     }
+
+    protected void testNearestPoints(HausdorffDistance vis, MeshModel primaryModel, MeshModel measuredModel) {
+        MeshFacet measuredFacet = measuredModel.getFacets().get(0);
+        MeshFacet primaryFacet = primaryModel.getFacets().get(0);
+
+        measuredModel.compute(vis);
+        Map<MeshFacet, List<Vector3d>> map = vis.getNearestPoints();
+
+        if(vis.getStrategy() == Strategy.POINT_TO_POINT_DISTANCE_ONLY){
+            assertTrue(map.isEmpty());
+        } else {
+            assertTrue(map.containsKey(measuredFacet));
+            List<Vector3d> results = map.get(measuredFacet);
+            for (int i = 0; i < measuredFacet.getNumberOfVertices(); i++) {
+                assertEquals(primaryFacet.getVertex(i).getPosition(), results.get(i));
+            }
+        }
+    }
     
     
     @Test
@@ -109,4 +125,16 @@ public class HausdorffDistanceTest {
         testDist(new HausdorffDistance(firstModel, Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, false, true), firstModel, secondModel, 0.5);
     }
 
+
+    @Test
+    public void correspondentNearestPointTest() {
+        MeshModel firstModel = getTrivialModel(1, 1);
+        MeshModel secondModel = getTrivialModel(1, 1);
+        MeshModel thirdModel = getTrivialModel(1.5, 1);
+        testNearestPoints(new HausdorffDistance(firstModel, Strategy.POINT_TO_POINT_DISTANCE_ONLY, false, false, false), firstModel, secondModel);
+        testNearestPoints(new HausdorffDistance(firstModel, Strategy.POINT_TO_POINT, false, false, false), firstModel, secondModel);
+        testNearestPoints(new HausdorffDistance(firstModel, Strategy.POINT_TO_POINT, false, false, false), firstModel, thirdModel);
+        testNearestPoints(new HausdorffDistance(firstModel, Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, false, false), firstModel, secondModel);
+    }
+
 }