From cda9762b868cb58be3fed5c94cfbb7d0a2c9395e Mon Sep 17 00:00:00 2001
From: Jakub Kolman <kubokolman@gmail.com>
Date: Tue, 30 Nov 2021 15:03:53 +0100
Subject: [PATCH] [#38] refactor: adding documantation and deleting dead code

---
 .../procrustes/ProcrustesAnalysis.java        | 199 +++---------------
 .../ProcrustesAnalysisFaceModel.java          |  36 +---
 .../utils/ProcrustesAnalysisUtils.java        |  77 -------
 .../analyst/feature/api/IPosition.java        |   1 +
 4 files changed, 44 insertions(+), 269 deletions(-)

diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java
index 400b13e9..43280fe2 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysis.java
@@ -27,9 +27,6 @@ public class ProcrustesAnalysis {
     private Point3d modelCentroid1;
     private Point3d modelCentroid2;
 
-    // based on some example models this is an approximate centroid of feature points
-//    private Point3d centroid  = new Point3d(0, 0, 0);
-
     /**
      * Constructor
      *
@@ -48,12 +45,8 @@ public class ProcrustesAnalysis {
             throw new ProcrustesAnalysisException("Lists of feature points do not have the same size");
         }
 
-//        this.orderedFeaturePointList1 = new ArrayList<>(model1.getFeaturePointsMap().values());
-//        this.orderedFeaturePointList2 = new ArrayList<>(model2.getFeaturePointsMap().values());
-
-        if (!featurePointTypesEquivalence(
-                model1.getFeaturePointValues(),
-                model2.getFeaturePointValues())) {
+        if (!ProcrustesAnalysisUtils.checkFeaturePointsType(
+                model1.getFeaturePointValues(), model2.getFeaturePointValues())) {
             throw new ProcrustesAnalysisException("Lists of feature points do not have the same feature point types");
         }
 
@@ -62,85 +55,42 @@ public class ProcrustesAnalysis {
 
         this.modelCentroid1 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model1.getFeaturePointValues());
         this.modelCentroid2 = ProcrustesAnalysisUtils.findCentroidOfFeaturePoints(model2.getFeaturePointValues());
-
-    }
-
-    public ProcrustesAnalysisFaceModel getFaceModel1() {
-        return faceModel1;
-    }
-
-    public ProcrustesAnalysisFaceModel getFaceModel2() {
-        return faceModel2;
     }
 
+    /**
+     * Method called for analysis after creating initial data in constructor. This method causes superimposition
+     * and rotation of the faces.
+     */
     public void analyze() {
-        List<SimpleMatrix> transformation = new ArrayList<>();
-
         this.superImpose();
         this.rotate();
     }
 
-    private Point3d computeCentroidsDistance(Point3d centroid1, Point3d centroid2) {
-        double x = (centroid1.x - centroid2.x);
-        double y = (centroid1.y - centroid2.y);
-        double z = (centroid1.z - centroid2.z);
-
-        Point3d computedCentroid = new Point3d(x, y, z);
-        return computedCentroid;
-    }
-
     /**
      * Imposes two face models (lists of feature points and vertices) over each other
      */
     private void superImpose() {
-
-        // moves vertices of face models
-//        moveModelToSameOrigin(this.faceModel2.getVertices(), this.faceModel2.getFeaturePointsMap());
-
-        normalize(this.faceModel1, this.modelCentroid1);
-        normalize(this.faceModel2, this.modelCentroid2);
-
-//        moveVertices(this.modelCentroid1, featurePointModel1.getVertices());
-//        moveModelToPoint(this.modelCentroid1, faceModel1.getVertices(), faceModel1.getFeaturePointsMap());
-//        moveModelToPoint(this.modelCentroid1, faceModel2.getVertices(), faceModel2.getFeaturePointsMap());
-    }
-
-    private void normalize(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
-//        float size = ProcrustesAnalysisUtils.countSize(centroid, faceModel.getFeaturePointsMap());
-        centerToOrigin(faceModel, centroid);
+        centerToOrigin(this.faceModel1, this.modelCentroid1);
+        centerToOrigin(this.faceModel2, this.modelCentroid2);
     }
 
+    /**
+     * Centers given face model to origin that is given centroid.
+     * Moves all vertices and feature points by value of difference between vertex/feature point and centroid.
+     *
+     * @param faceModel
+     * @param centroid
+     */
     private void centerToOrigin(ProcrustesAnalysisFaceModel faceModel, Point3d centroid) {
         for (FeaturePoint fp: faceModel.getFeaturePointsMap().values()) {
             fp.getPosition().x -= centroid.x;
             fp.getPosition().y -= centroid.y;
             fp.getPosition().z -= centroid.z;
         }
-        SimpleMatrix centeredVertices = new SimpleMatrix(
-                faceModel.getVerticesMatrix().numRows(), faceModel.getVerticesMatrix().numCols());
-        for (int i = 0; i < faceModel.getVerticesMatrix().numRows(); i++) {
-            centeredVertices.set(i, 0, faceModel.getVerticesMatrix().get(i, 0) - centroid.x);
-            centeredVertices.set(i, 1, faceModel.getVerticesMatrix().get(i, 1) - centroid.y);
-            centeredVertices.set(i, 2, faceModel.getVerticesMatrix().get(i, 2) - centroid.z);
-        }
-        faceModel.setVerticesMatrix(centeredVertices);
-    }
-
-    private void moveModelToSameOrigin(List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap) {
-        Point3d diff = computeCentroidsDistance(this.modelCentroid1, this.modelCentroid2);
-        moveModelToPoint(diff, vertices, featurePointsMap);
-    }
-
-    private void moveModelToPoint(Point3d centroid, List<MeshPoint> vertices, HashMap<Integer, FeaturePoint> featurePointsMap) {
-        moveVertices(centroid, vertices);
-        moveFeaturePointsToVertices(centroid, featurePointsMap);
-    }
-
-    private void moveFeaturePointsToVertices(Point3d centroid, HashMap<Integer, FeaturePoint> featurePointsMap) {
-        for (FeaturePoint fp : featurePointsMap.values()) {
-            fp.getPosition().x = fp.getPosition().x + centroid.x;
-            fp.getPosition().y = fp.getPosition().y + centroid.y;
-            fp.getPosition().z = fp.getPosition().z + centroid.z;
+        for (MeshPoint v : faceModel.getVertices()) {
+            v.getPosition().x = v.getX() - centroid.x;
+            v.getPosition().y = v.getY() - centroid.y;
+            v.getPosition().z = v.getZ() - centroid.z;
         }
     }
 
@@ -148,11 +98,6 @@ public class ProcrustesAnalysis {
      * By rotation of matrices solves orthogonal procrustes problem
      */
     private void rotate() {
-
-        // There is no reason trying to rotate less than 3 elements
-        if (this.getFaceModel1().getFeaturePointsMap().size() < 3) {
-            throw new ProcrustesAnalysisException("To do procrustes analysis models have to have at least 3 feature points");
-        }
         SimpleMatrix primaryMatrix = ProcrustesAnalysisUtils.createMatrixFromList(this.faceModel2.getFeaturePointValues());
         SimpleMatrix transposedMatrix = ProcrustesAnalysisUtils.createMatrixFromList(
                 this.faceModel1.getFeaturePointValues()).transpose();
@@ -160,44 +105,23 @@ public class ProcrustesAnalysis {
         SimpleMatrix svdMatrix = transposedMatrix.mult(primaryMatrix);
         SimpleSVD<SimpleMatrix> singularValueDecomposition = svdMatrix.svd();
         SimpleMatrix transposedU = singularValueDecomposition.getU().transpose();
-        SimpleMatrix r = singularValueDecomposition.getV().mult(transposedU);
-        primaryMatrix = primaryMatrix.mult(r);
+        SimpleMatrix rotationMatrix = singularValueDecomposition.getV().mult(transposedU);
+        primaryMatrix = primaryMatrix.mult(rotationMatrix);
 
         this.faceModel2.setFeaturePointsMap(
                 ProcrustesAnalysisUtils.createFeaturePointMapFromMatrix(
                         primaryMatrix, this.faceModel2));
 
-//        for (int i = 0; i < this.faceModel2.getFeaturePointTypeCorrespondence().size(); i++) {
-//            FeaturePoint fp = new FeaturePoint(
-//                    primaryMatrix.get(i, 0),
-//                    primaryMatrix.get(i, 1),
-//                    primaryMatrix.get(i, 2),
-//                    this.faceModel2.getFeaturePointsMap().get(
-//                            this.faceModel2.getFeaturePointTypeCorrespondence().get(i)).getFeaturePointType()
-//            );
-//            this.faceModel2.getFeaturePointsMap().put(i, fp);
-//        }
-
-        rotateVertices(this.faceModel2.getVertices(), r);
-
-//        SimpleMatrix rotatedVertices = this.faceModel2.getVerticesMatrix().mult(r);
-//        createListFromMatrix(rotatedVertices, this.faceModel2);
+        rotateVertices(this.faceModel2.getVertices(), rotationMatrix);
     }
 
-    private void createListFromMatrix(SimpleMatrix rotatedVertices, ProcrustesAnalysisFaceModel faceModel) {
-        if (faceModel.getVertices() != null) {
-            for (int i = 0; i < rotatedVertices.numRows(); i++) {
-                faceModel.getVertices().get(i).getPosition().x = rotatedVertices.get(i, 0);
-                faceModel.getVertices().get(i).getPosition().y = rotatedVertices.get(i, 1);
-                faceModel.getVertices().get(i).getPosition().z = rotatedVertices.get(i, 2);
-            }
-        }
-    }
 
     /**
-     * Rotates every vertex of model by given matrix
+     * Rotates all vertices.
      *
-     * @param model
+     * For more details check out single vertex rotation {@link #rotateVertex}.
+     *
+     * @param vertices
      * @param matrix
      */
     // if rotated vertices are drawn immediately it is better to set them after rotating them all
@@ -210,7 +134,13 @@ public class ProcrustesAnalysis {
         }
     }
 
-    public static void rotateVertex(MeshPoint v,SimpleMatrix matrix) {
+    /**
+     * Rotates vertex v by simulating matrix multiplication with given matrix
+     *
+     * @param v
+     * @param matrix
+     */
+    private static void rotateVertex(MeshPoint v, SimpleMatrix matrix) {
         double x = ((v.getX() * matrix.get(0, 0))
                 + (v.getY() * matrix.get(1, 0))
                 + (v.getZ() * matrix.get(2, 0)));
@@ -225,67 +155,4 @@ public class ProcrustesAnalysis {
         v.getPosition().z = z;
     }
 
-    /**
-     * Calculates new vertices adjusted to the centroid by method {@see findCenteroidOfFeaturePoints},
-     * so moved featurepoints would correspond with the same place on face as they did before.
-     *
-     * @param centroid
-     * @param vertices
-     * @return
-     */
-    private void moveVertices(Point3d centroid, List<MeshPoint> vertices) {
-        if (vertices != null && centroid != null) {
-//            List<MeshPoint> movedVertices = null;
-            for (MeshPoint v : vertices) {
-                v.getPosition().x = (v.getPosition().x + centroid.x);
-                v.getPosition().y = (v.getPosition().y + centroid.y);
-                v.getPosition().z = (v.getPosition().z + centroid.z);
-            }
-        } else {
-            throw new ProcrustesAnalysisException("Could not compute vertices locations after moving the centroid from model to feature points");
-        }
-    }
-
-    /**
-     * Creates sorted feature point lists and compares them whether they have
-     * the same feature point types.
-     *
-     * @param fpList1
-     * @param fpList2
-     * @return
-     */
-    private boolean featurePointTypesEquivalence(List<FeaturePoint> fpList1, List<FeaturePoint> fpList2) {
-        return ProcrustesAnalysisUtils.checkFeaturePointsType(fpList1, fpList2);
-    }
-
-    /**
-     * Calculate scaling ratio of how much the appropriate object corresponding
-     * to the second feature point list has to be scale up or shrunk.
-     * <p>
-     * If returned ratioValue is greater 1 then it means that the second object
-     * should be scaled up ratioValue times. If returned ratioValue is smaller 1
-     * than the second object should be shrunk.
-     *
-     * @return ratioValue
-     */
-//    private double calculateScalingValue() {
-//        double[] distancesOfList1 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
-//                this.faceModel1.getFeaturePointValues());
-//        double[] distancesOfList2 = ProcrustesAnalysisUtils.calculateMeanDistancesFromOrigin(
-//                this.faceModel2.getFeaturePointValues());
-//
-//        double[] ratioArray = new double[distancesOfList1.length];
-//        double ratioValue = 0;
-//
-//        for (int i = 0; i < distancesOfList1.length; i++) {
-//            ratioArray[i] += distancesOfList1[i] / distancesOfList2[i];
-//        }
-//
-//        for (double ratio : ratioArray) {
-//            ratioValue += ratio;
-//        }
-//
-//        return ratioValue / distancesOfList1.length;
-//    }
-
 }
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java
index d828f00f..35b5114b 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/ProcrustesAnalysisFaceModel.java
@@ -26,7 +26,6 @@ public class ProcrustesAnalysisFaceModel {
     private final HumanFace humanFace;
     private HashMap<Integer, FeaturePoint> featurePointsMap;        // sorted by feature point type
     private List<MeshPoint> vertices;
-    private SimpleMatrix verticesMatrix;
     private MeshModel meshModel;
     private final HashMap<Integer, Integer> featurePointTypeCorrespondence;
 
@@ -43,8 +42,6 @@ public class ProcrustesAnalysisFaceModel {
         this.featurePointsMap = createFeaturePointMap(
                 ProcrustesAnalysisUtils.sortListByFeaturePointType(modifiableFeaturePointList));
         this.featurePointTypeCorrespondence = createFeaturePointTypeCorrespondence(face.getFeaturePoints());
-        this.verticesMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableVertices);
-//        this.featurePointMatrix = ProcrustesAnalysisUtils.createMatrixFromList(modifiableFeaturePointList);
     }
 
     /**
@@ -74,28 +71,19 @@ public class ProcrustesAnalysisFaceModel {
         return featurePointsMap;
     }
 
+    public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() {
+        return featurePointTypeCorrespondence;
+    }
+
     /**
-     * sets vertices map and also sets feature point on human face for visualisation
+     * Creates feature point hash map for internal use in Procrustes Analysis.
+     *
+     * Map key is feature point type (Integer).
+     * Value is feature point itself.
      *
-     * @param verticesMatrix
+     * @param featurePointList
+     * @return
      */
-    public void setVerticesMatrix(SimpleMatrix verticesMatrix) {
-        this.verticesMatrix = verticesMatrix;
-        changeVerticesValues(verticesMatrix);
-    }
-
-    public SimpleMatrix getVerticesMatrix() {
-        return verticesMatrix;
-    }
-
-    private void changeVerticesValues(SimpleMatrix matrix) {
-        for (int i = 0; i < vertices.size(); i++) {
-            vertices.get(i).getPosition().x = (float) matrix.get(i, 0);
-            vertices.get(i).getPosition().y = (float) matrix.get(i, 1);
-            vertices.get(i).getPosition().z = (float) matrix.get(i, 2);
-        }
-    }
-
     private HashMap<Integer, FeaturePoint> createFeaturePointMap(List<FeaturePoint> featurePointList) {
         HashMap<Integer, FeaturePoint> map = new HashMap<>();
         for (FeaturePoint fp: featurePointList) {
@@ -104,10 +92,6 @@ public class ProcrustesAnalysisFaceModel {
         return map;
     }
 
-    public HashMap<Integer, Integer> getFeaturePointTypeCorrespondence() {
-        return featurePointTypeCorrespondence;
-    }
-
     /**
      * Creates corresponding key value pair of matrix row index and a feature point type value.
      * It is used in {@link cz.fidentis.analyst.procrustes.utils.ProcrustesAnalysisUtils#createFeaturePointMapFromMatrix}
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/utils/ProcrustesAnalysisUtils.java b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/utils/ProcrustesAnalysisUtils.java
index 78baf70d..7d278cc5 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/procrustes/utils/ProcrustesAnalysisUtils.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/procrustes/utils/ProcrustesAnalysisUtils.java
@@ -34,21 +34,6 @@ public class ProcrustesAnalysisUtils {
         return featurePointList;
     }
 
-    /**
-     * Creates hash map with a key feature point type and value feature point
-     * @param featurePointList
-     * @return
-     */
-    public static HashMap<Integer, FeaturePoint> generateFeaturePointHashMap(List<FeaturePoint> featurePointList) {
-        HashMap<Integer, FeaturePoint> map = new HashMap<>();
-        for (FeaturePoint fp : featurePointList) {
-            if (fp.getFeaturePointType().getType() > 0) {
-                map.put(fp.getFeaturePointType().getType(), fp);
-            }
-        }
-        return map;
-    }
-
     /**
      * Checks if two feature point lists have the same types of feature points.
      * <p>
@@ -75,20 +60,6 @@ public class ProcrustesAnalysisUtils {
         return true;
     }
 
-    /**
-     * Creates array of distance values from feature point to origin (0,0,0).
-     *
-     * @param featurePointList
-     * @return array of distances
-     */
-    public static double[] calculateMeanDistancesFromOrigin(List<FeaturePoint> featurePointList) {
-        double[] distances = new double[featurePointList.size()];
-        for (int i = 0; i < featurePointList.size(); i++) {
-            distances[i] = calculatePointDistanceFromOrigin(featurePointList.get(i));
-        }
-        return distances;
-    }
-
     /**
      * Finds centrioid from given feature point List
      *
@@ -107,33 +78,6 @@ public class ProcrustesAnalysisUtils {
         return new Point3d(x / featurePointList.size(), y / featurePointList.size(), z / featurePointList.size());
     }
 
-    /**
-     * Calculates distance of one feature point from another
-     *
-     * @param fp1
-     * @param fp2
-     * @return distance
-     */
-    public static double calculateDistanceOfTwoPoints(FeaturePoint fp1, FeaturePoint fp2) {
-        return Math.sqrt(
-                (Math.pow(fp1.getX(), 2) - Math.pow(fp2.getX(), 2))
-                        + (Math.pow(fp1.getY(), 2) - Math.pow(fp2.getY(), 2))
-                        + (Math.pow(fp1.getZ(), 2) - Math.pow(fp2.getZ(), 2)));
-    }
-
-    /**
-     * Calculates distance of single feature point from origin (0,0,0)
-     *
-     * @param fp
-     * @return distance
-     */
-    public static double calculatePointDistanceFromOrigin(FeaturePoint fp) {
-        return Math.sqrt(
-                Math.pow(fp.getX(), 2)
-                        + Math.pow(fp.getY(), 2)
-                        + Math.pow(fp.getZ(), 2));
-    }
-
     /**
      * Creates matrix from given feature point list
      *
@@ -174,25 +118,4 @@ public class ProcrustesAnalysisUtils {
         return map;
     }
 
-
-    public static float countSize(Point3d point, HashMap<Integer, FeaturePoint> featurePointsMap) {
-        float size = 0;
-        for (FeaturePoint fp: featurePointsMap.values()) {
-            size += (fp.getX() - point.x) * (fp.getX() - point.x);
-            size += (fp.getY() - point.y) * (fp.getY() - point.y);
-            size += (fp.getZ() - point.z) * (fp.getZ() - point.z);
-        }
-        return ((float) Math.sqrt(size));
-    }
-
-//    public List<MeshPoint> CreateVerticesListFromMatrix (SimpleMatrix matrix) {
-//        List<MeshPoint> verticesList = new ArrayList<>();
-//        for (int i = 0; i < matrix.numRows(); i++) {
-//            float x = (float) matrix.get(i, 0);
-//            float y = (float) matrix.get(i, 1);
-//            float z = (float) matrix.get(i, 2);
-//            verticesList.add(new MeshPoint() {
-//            })
-//        }
-//    }
 }
diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/feature/api/IPosition.java b/MeshModel/src/main/java/cz/fidentis/analyst/feature/api/IPosition.java
index 3b7d412f..f1aea467 100644
--- a/MeshModel/src/main/java/cz/fidentis/analyst/feature/api/IPosition.java
+++ b/MeshModel/src/main/java/cz/fidentis/analyst/feature/api/IPosition.java
@@ -8,6 +8,7 @@ package cz.fidentis.analyst.feature.api;
 import javax.vecmath.Point3d;
 
 /**
+ * Interface for working.
  *
  * @author Jakub Kolman
  */
-- 
GitLab