diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitor.java
index 01f5191da75811cb449ebe530f1f2a2d331b497e..7c8ed4fa36c6e0ecffa68e1faa19d5582e8f9c75 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitor.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitor.java
@@ -16,12 +16,12 @@ import javax.vecmath.Vector3d;
  * 
  * Because there can be multiple triangles with the same minimal distance, the visitor
  * returns a list of mesh facets and a list of indices corresponding 
- * to the facets. Returned lists have the same size and i-th mesh point index 
- * corresponds to the i-th mesh facet.
- 
- * 
- * This visitor is instantiated on a single mesh facet or multiple facets. 
- * Then, when applied to other facets, it computes Huasdorff distance to these facets.
+ * to the facets.  
+ *
+ * Returned lists have the same size. 
+ * {@code n = getIndices().get(i)} returns the index of the closest triangle on the i-th facet.
+ * Then iterate into the n-th triangle of facet {@code getClosestFacets().get(i)} to get 
+ * the triangle instance.
  * 
  * @author Matej Lukes
  * @author Radek Oslejsek
@@ -51,39 +51,17 @@ public class Point2MeshTriVisitor extends Point2MeshVisitor {
     
     @Override
     public void visitMeshFacet(MeshFacet facet) {
-        Vector3d helperVector = new Vector3d();
-        Vector3d vertexPosition = getMyPoint().getPosition();
+        Vector3d my = getMyPoint().getPosition();
         int i = 0;
-        
         for (MeshTriangle tri: facet) {
-            Vector3d projection = getProjectionToTrianglePlane(vertexPosition, tri);
-
+            Vector3d projection = getProjectionToTrianglePlane(my, tri);
             if (!isPointInTriangle(projection, tri)) {
                 projection = getProjectionToClosestEdge(projection, tri);
             }
-
-            helperVector.sub(vertexPosition, projection);
-            double dist = helperVector.length();
-            double currentDist = getDistance();
-            
-            if (dist > currentDist) {
-                i++;
-                continue;
-            }
-            if (dist < currentDist) { // new closest point
-                setDistance(dist);
-                getModifClosestFacets().clear();
-                getModifIndices().clear();
-                getModifClosestFacets().add(facet);
-                getModifIndices().add(i++);
-            } else { // the same distance
-                getModifClosestFacets().add(facet);
-                getModifIndices().add(i++);
-            }
+            checkAndUpdateDistance(projection, facet, i);
         }        
     }
     
-    
     /**
      * returns perpendicular projection from vertex to plane of triangle
      *
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitor.java
index be06e2052cf28ab35e2768c9cd2e5e82e7502ed3..0a043a4289ce05dcb16dc86de688d63e0cf6b6f0 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitor.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitor.java
@@ -60,26 +60,7 @@ public class Point2MeshVisitor implements MeshVisitor {
     public void visitMeshFacet(MeshFacet facet) {
         List<MeshPoint> vertices = facet.getVertices();
         for (int i = 0; i < vertices.size(); i++) {
-            MeshPoint otherPoint = vertices.get(i);
-            
-            Vector3d aux = new Vector3d(otherPoint.getPosition());
-            aux.sub(myPoint.getPosition());
-            sign = relativeDist ? (int) Math.signum(aux.dot(myPoint.getNormal())): 1;
-            double dist = aux.length();
-            
-            if (dist > distance) {
-                continue;
-            }
-            if (dist < distance) { // new closest point
-                distance = dist;
-                closestFacets.clear();
-                indices.clear();
-                closestFacets.add(facet);
-                indices.add(i);
-            } else { // the same distance
-                closestFacets.add(facet);
-                indices.add(i);
-            }
+            checkAndUpdateDistance(vertices.get(i).getPosition(), facet, i);
         }
     }
     
@@ -147,4 +128,26 @@ public class Point2MeshVisitor implements MeshVisitor {
     protected List<MeshFacet> getModifClosestFacets() {
         return closestFacets;
     }
+    
+    protected void checkAndUpdateDistance(Vector3d other, MeshFacet facet, int index) {
+        Vector3d aux = new Vector3d(other);
+        aux.sub(myPoint.getPosition());
+        sign = relativeDist ? (int) Math.signum(aux.dot(myPoint.getNormal())): 1;
+        double dist = aux.length();
+            
+        if (dist > distance) {
+            return;
+        }
+        
+        if (dist < distance) { // new closest point
+            distance = dist;
+            closestFacets.clear();
+            indices.clear();
+            closestFacets.add(facet);
+            indices.add(index);
+        } else { // the same distance
+            closestFacets.add(facet);
+            indices.add(index);
+        }
+    }
 }
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitorTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9fbaae3b7e50458416c6dc8e7a81cb5d4983a9fb
--- /dev/null
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshTriVisitorTest.java
@@ -0,0 +1,320 @@
+package cz.fidentis.analyst.mesh.visitors;
+
+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.MeshPoint;
+import cz.fidentis.analyst.mesh.core.MeshPointImpl;
+import cz.fidentis.analyst.mesh.core.MeshTriangle;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import javax.vecmath.Vector3d;
+import org.junit.jupiter.api.Assertions;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import org.junit.jupiter.api.Test;
+
+/**
+ *
+ * @author oslejsek
+ */
+public class Point2MeshTriVisitorTest {
+    private MeshFacet getTrivialFacet(double offset, double size) {
+        MeshFacet facet = new MeshFacetImpl();
+        facet.addVertex(new MeshPointImpl(new Vector3d(0, 0, offset), new Vector3d(0, 0, 1), new Vector3d()));
+        facet.addVertex(new MeshPointImpl(new Vector3d(size, 0, offset), new Vector3d(0, 0, 1), new Vector3d()));
+        facet.addVertex(new MeshPointImpl(new Vector3d(0, size, offset), new Vector3d(0, 0, 1), new Vector3d()));
+
+        facet.getCornerTable().addRow(new CornerTableRow(0, -1));
+        facet.getCornerTable().addRow(new CornerTableRow(1, -1));
+        facet.getCornerTable().addRow(new CornerTableRow(2, -1));
+
+        return facet;
+    }
+
+    @Test
+    public void absoluteDistTest() {
+        MeshFacet facet = getTrivialFacet(1.5, 1);
+        MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
+        
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false);
+        facet.accept(vis);
+        assertEquals(1.5, vis.getDistance());
+        
+        List<Integer> closestPoints = vis.getIndices();
+        List<MeshFacet> closestMeshes = vis.getClosestFacets();
+        assertNotNull(closestPoints);
+        assertNotNull(closestMeshes);
+        assertEquals(1, closestPoints.size());
+        assertEquals(1, closestMeshes.size());
+        assertEquals(facet, closestMeshes.get(0));
+        assertEquals(0, closestPoints.get(0));
+    }
+    
+    @Test
+    public void relativeDistTest() {
+        MeshFacet facet = getTrivialFacet(1.5, 1);
+        MeshPoint point = new MeshPointImpl(new Vector3d(0,0,0), new Vector3d(0,0,-1), new Vector3d());
+        
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, true);
+        facet.accept(vis);
+        assertEquals(-1.5, vis.getDistance());
+        
+        List<Integer> closestPoints = vis.getIndices();
+        List<MeshFacet> closestMeshes = vis.getClosestFacets();
+        assertNotNull(closestPoints);
+        assertNotNull(closestMeshes);
+        assertEquals(1, closestPoints.size());
+        assertEquals(1, closestMeshes.size());
+        assertEquals(facet, closestMeshes.get(0));
+        assertEquals(0, closestPoints.get(0));
+    }
+    
+    @Test
+    public void exactMatchTest() {
+        MeshFacet facet = getTrivialFacet(1.5, 1);
+        MeshPoint point = new MeshPointImpl(new Vector3d(0, 0, 1.5), new Vector3d(0, 0, 1), new Vector3d());
+        
+        System.out.println(facet.getVertices());
+        
+        Point2MeshVisitor vis = new Point2MeshTriVisitor(point, false);
+        facet.accept(vis);
+        assertEquals(0, vis.getDistance());
+        
+        System.out.println(facet.getVertices());
+        
+        List<Integer> closestPoints = vis.getIndices();
+        List<MeshFacet> closestMeshes = vis.getClosestFacets();
+        assertNotNull(closestPoints);
+        assertNotNull(closestMeshes);
+        assertEquals(1, closestPoints.size());
+        assertEquals(1, closestMeshes.size());
+        assertEquals(facet, closestMeshes.get(0));
+        assertEquals(0, closestPoints.get(0));
+    }
+    
+    @Test
+    public void getProjectionToTrianglePlaneTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToTrianglePlane", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(0, 0.5, 1);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(0d, result.x);
+        Assertions.assertEquals(0.5d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void getProjectionToTrianglePlaneBelowPLaneTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToTrianglePlane", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(0, 0.5, 1);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(0d, result.x);
+        Assertions.assertEquals(0.5d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void isPointInTriangleInsideTriangleTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("isPointInTriangle", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(1.2, 0.2, 0);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        boolean result = (boolean) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertTrue(result);
+    }
+
+    @Test
+    public void isPointInTriangleOutsideTriangleTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("isPointInTriangle", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(0, 0.5, 0);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        boolean result = (boolean) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertFalse(result);
+    }
+
+    @Test
+    public void getProjectionToClosestEdgeTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToClosestEdge", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(0, 0.5, 0);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(1d, result.x);
+        Assertions.assertEquals(0.5d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void getProjectionToClosestEdgeNormalProjectionOutsideEdgeTestTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[2];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = MeshTriangle.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToClosestEdge", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[2];
+
+        args[0] = new Vector3d(0, -0.5, 0);
+        MeshTriangle triangle = new MeshTriangle(
+                new MeshPointImpl(new Vector3d(1, 0, 0), null, null),
+                new MeshPointImpl(new Vector3d(1, 2, 0), null, null),
+                new MeshPointImpl(new Vector3d(2, 0, 0), null, null)
+        );
+        args[1] = triangle;
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(1d, result.x);
+        Assertions.assertEquals(0d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void getProjectionToEdgeTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[3];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = Vector3d.class;
+        argClasses[2] = Vector3d.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToEdge", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[3];
+
+        args[0] = new Vector3d(0, 0.5, 0);
+        args[1] = new Vector3d(1, 2, 0);
+        args[2] = new Vector3d(1, 0, 0);
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(1d, result.x);
+        Assertions.assertEquals(0.5d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void getProjectionToEdgeNormalProjectionOutsideEdgeTest()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[3];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = Vector3d.class;
+        argClasses[2] = Vector3d.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToEdge", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[3];
+
+        args[0] = new Vector3d(0, -0.5, 0);
+        args[1] = new Vector3d(1, 2, 0);
+        args[2] = new Vector3d(1, 0, 0);
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(1d, result.x);
+        Assertions.assertEquals(0d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+    @Test
+    public void getProjectionToEdgeNormalProjectionOutsideEdge2Test()
+            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Class<?>[] argClasses = new Class[3];
+        argClasses[0] = Vector3d.class;
+        argClasses[1] = Vector3d.class;
+        argClasses[2] = Vector3d.class;
+        Method method = Point2MeshTriVisitor.class.getDeclaredMethod("getProjectionToEdge", argClasses);
+        method.setAccessible(true);
+        Object[] args = new Object[3];
+
+        args[0] = new Vector3d(0, 2.5, 0);
+        args[1] = new Vector3d(1, 2, 0);
+        args[2] = new Vector3d(1, 0, 0);
+
+        Point2MeshTriVisitor hausdorffDistance = new Point2MeshTriVisitor(new MeshPointImpl(new Vector3d(), null, null), false);
+        Vector3d result = (Vector3d) method.invoke(hausdorffDistance, args);
+
+        Assertions.assertEquals(1d, result.x);
+        Assertions.assertEquals(2d, result.y);
+        Assertions.assertEquals(0d, result.z);
+    }
+
+}
diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitorTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitorTest.java
index 5e34764a983dad94d79304d1149ace06b0d454c3..1a53154a39821e1c2539e7dbfaebbef733f038b1 100644
--- a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitorTest.java
+++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/visitors/Point2MeshVisitorTest.java
@@ -11,10 +11,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import org.junit.jupiter.api.Test;
 
-/**
- *
- * @author oslejsek
- */
 public class Point2MeshVisitorTest {
     private MeshFacet getTrivialFacet(double offset, double size) {
         MeshFacet facet = new MeshFacetImpl();
@@ -78,8 +74,6 @@ public class Point2MeshVisitorTest {
         facet.accept(vis);
         assertEquals(0, vis.getDistance());
         
-        System.out.println(facet.getVertices());
-        
         List<Integer> closestPoints = vis.getIndices();
         List<MeshFacet> closestMeshes = vis.getClosestFacets();
         assertNotNull(closestPoints);