diff --git a/src/algorithm/geometry.hpp b/src/algorithm/geometry.hpp
index 33b6b8a3a5dcc3d89c57b94335a0b39e4286f576..f7303a1451a6350b17880e6942e9404eb847f47c 100644
--- a/src/algorithm/geometry.hpp
+++ b/src/algorithm/geometry.hpp
@@ -70,14 +70,24 @@ namespace se3
                                 const bool stopAtFirstCollision = false
                                 );
 
-  inline void computeDistances(GeometryData & data_geom);
+  /// Compute the distances of all collision pairs
+  ///
+  /// \param ComputeShortest default to true.
+  /// \param data_geom
+  /// \return When ComputeShortest is true, the index of the collision pair which has the shortest distance.
+  ///         When ComputeShortest is false, the number of collision pairs.
+  template <bool ComputeShortest>
+  inline std::size_t computeDistances(GeometryData & data_geom);
 
-  inline void computeDistances(const Model & model,
-                              Data & data,
-                              const GeometryModel & model_geom,
-                              GeometryData & data_geom,
-                              const Eigen::VectorXd & q
-                              );
+  /// Compute the forward kinematics, update the goemetry placements and
+  /// calls computeDistances(GeometryData&).
+  template <bool ComputeShortest>
+  inline std::size_t computeDistances(const Model & model,
+                                      Data & data,
+                                      const GeometryModel & model_geom,
+                                      GeometryData & data_geom,
+                                      const Eigen::VectorXd & q
+                                      );
 
   inline void computeBodyRadius(const Model &         model,
                                 const GeometryModel & geomModel,
diff --git a/src/algorithm/geometry.hxx b/src/algorithm/geometry.hxx
index c10a7081b5bed72c4db06e978e2a6a3c10717e35..e32f9864844283240c78d84880ba80db2ba3aa47 100644
--- a/src/algorithm/geometry.hxx
+++ b/src/algorithm/geometry.hxx
@@ -78,16 +78,43 @@ namespace se3
     
     return computeCollisions(data_geom, stopAtFirstCollision);
   }
+
+  // Required to have a default template argument on templated free function
+  inline std::size_t computeDistances(GeometryData & data_geom)
+  {
+    return computeDistances<true>(data_geom);
+  }
   
-  
-  inline void computeDistances(GeometryData & data_geom)
+  template <bool ComputeShortest>
+  inline std::size_t computeDistances(GeometryData & data_geom)
   {
+    double min_dist = std::numeric_limits<double>::infinity();
+    std::size_t min_index = data_geom.collision_pairs.size();
     for (std::size_t cpt = 0; cpt < data_geom.collision_pairs.size(); ++cpt)
+    {
       data_geom.distance_results[cpt] = data_geom.computeDistance(data_geom.collision_pairs[cpt].first,
                                                                   data_geom.collision_pairs[cpt].second);
+      if (ComputeShortest && data_geom.distance_results[cpt].distance() < min_dist) {
+        min_index = cpt;
+        min_dist = data_geom.distance_results[cpt].distance();
+      }
+    }
+    return min_index;
   }
   
-  inline void computeDistances(const Model & model,
+  // Required to have a default template argument on templated free function
+  inline std::size_t computeDistances(const Model & model,
+                               Data & data,
+                               const GeometryModel & model_geom,
+                               GeometryData & data_geom,
+                               const Eigen::VectorXd & q
+                               )
+  {
+    return computeDistances<true>(model, data, model_geom, data_geom, q);
+  }
+
+  template <bool ComputeShortest>
+  inline std::size_t computeDistances(const Model & model,
                                Data & data,
                                const GeometryModel & model_geom,
                                GeometryData & data_geom,
@@ -95,7 +122,7 @@ namespace se3
                                )
   {
     updateGeometryPlacements (model, data, model_geom, data_geom, q);
-    computeDistances(data_geom);
+    return computeDistances<ComputeShortest>(data_geom);
   }
 
   /// Given p1..3 being either "min" or "max", return one of the corners of the