From 173d0648d9c842c3f8fcb2c3bf014ae97709575b Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Tue, 24 Aug 2021 19:21:24 +0200
Subject: [PATCH] [geometry] Add simple bounding sphere algorithm

---
 dumux/geometry/boundingsphere.hh | 97 ++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 dumux/geometry/boundingsphere.hh

diff --git a/dumux/geometry/boundingsphere.hh b/dumux/geometry/boundingsphere.hh
new file mode 100644
index 0000000000..993f02c87b
--- /dev/null
+++ b/dumux/geometry/boundingsphere.hh
@@ -0,0 +1,97 @@
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 3 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \ingroup Geometry
+ * \brief A function to compute bounding spheres of points clouds or convex polytopes
+ */
+#ifndef DUMUX_GEOMETRY_BOUNDINGSPHERE_HH
+#define DUMUX_GEOMETRY_BOUNDINGSPHERE_HH
+
+#include <algorithm>
+#include <vector>
+
+#include <dumux/geometry/sphere.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup Geometry
+ * \brief Computes a bounding sphere of a convex polytope geometry (Dune::Geometry interface)
+ * \note The bounding sphere is not necessarily the minimum enclosing sphere
+ *       but computation is fast (AABB method)
+ */
+template<class ConvexGeometry>
+static inline Sphere<typename ConvexGeometry::ctype, ConvexGeometry::coorddimension>
+boundingSphere(const ConvexGeometry& geometry)
+{
+    constexpr int dimWorld = ConvexGeometry::coorddimension;
+    assert(geometry.corners() >= 1);
+
+    auto corner = geometry.corner(0);
+    auto xMin = corner, xMax = corner;
+    using std::max; using std::min;
+
+    // Compute the min and max over the remaining vertices
+    for (std::size_t i = 1; i < geometry.corners(); ++i)
+    {
+        corner = geometry.corner(i);
+        for (std::size_t dimIdx = 0; dimIdx < dimWorld; ++dimIdx)
+        {
+            xMin[dimIdx] = min(xMin[dimIdx], corner[dimIdx]);
+            xMax[dimIdx] = max(xMax[dimIdx], corner[dimIdx]);
+        }
+    }
+
+    auto center = 0.5*xMax + xMin;
+    auto radius = (center-xMax).two_norm();
+    return { std::move(center), std::move(radius) };
+}
+
+namespace Detail {
+template<class Scalar, int dim>
+struct PointsToGeometryWrapper
+{
+    const std::vector<Dune::FieldVector<Scalar, dim>>& points_;
+    PointsToGeometryWrapper(const std::vector<Dune::FieldVector<Scalar, dim>>& points)
+    : points_(points) {}
+
+    static constexpr int coorddimension = dim;
+    using ctype = Scalar;
+
+    auto corners() const { return points_.size(); }
+    const auto& corner(std::size_t i) const { return points_[i]; }
+};
+} // end namespace Detail
+
+/*!
+ * \ingroup Geometry
+ * \brief Computes a bounding sphere of points
+ * \note The bounding sphere is not necessarily the minimum enclosing sphere
+ *       but computation is fast (AABB method)
+ */
+template<class Scalar, int dim>
+static inline Sphere<Scalar, dim>
+boundingSphere(const std::vector<Dune::FieldVector<Scalar, dim>>& points)
+{
+    Detail::PointsToGeometryWrapper<Scalar, dim> geometry(points);
+    return boundingSphere(geometry);
+}
+
+} // end namespace Dumux
+
+#endif
-- 
GitLab