Skip to content
Snippets Groups Projects
Commit 9a8dafc4 authored by Karsten Rink's avatar Karsten Rink
Browse files

renamed class, adjusted dates, shortened det calculation

parent 8a0a451a
No related branches found
No related tags found
No related merge requests found
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
* \file Calculation of a minimum bounding sphere for a vector of points * \file Calculation of a minimum bounding sphere for a vector of points
* \author Karsten Rink * \author Karsten Rink
* \date 2014-07-11 * \date 2014-07-11
* \brief Implementation of the BoundingSphere class. * \brief Implementation of the MinimalBoundingSphere class.
* *
* \copyright * \copyright
* Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License. * Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or * See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license * http://www.opengeosys.org/project/license
* *
*/ */
#include "BoundingSphere.h" #include "MinimalBoundingSphere.h"
#include <ctime> #include <ctime>
...@@ -21,33 +21,17 @@ ...@@ -21,33 +21,17 @@
namespace GeoLib { namespace GeoLib {
BoundingSphere::BoundingSphere() MinimalBoundingSphere::MinimalBoundingSphere()
: _radius(-1), _center(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max()) : _radius(-1), _center(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max())
{ {
} }
BoundingSphere::BoundingSphere(BoundingSphere const& sphere) MinimalBoundingSphere::MinimalBoundingSphere(GeoLib::Point const& p, double radius)
: _radius(sphere.getRadius()), _center(sphere.getCenter())
{
}
BoundingSphere::BoundingSphere(BoundingSphere const&& sphere)
: _radius(sphere.getRadius()), _center(sphere.getCenter())
{
}
BoundingSphere::BoundingSphere(GeoLib::Point const& p)
: _radius(std::numeric_limits<double>::epsilon()), _center(p)
{
}
BoundingSphere::BoundingSphere(GeoLib::Point const& p, double radius)
: _radius(radius), _center(p) : _radius(radius), _center(p)
{ {
} }
BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q) MinimalBoundingSphere::MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q)
: _radius(std::numeric_limits<double>::epsilon()), _center(p) : _radius(std::numeric_limits<double>::epsilon()), _center(p)
{ {
MathLib::Vector3 const a(p, q); MathLib::Vector3 const a(p, q);
...@@ -60,7 +44,7 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q) ...@@ -60,7 +44,7 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q)
} }
} }
BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r) MinimalBoundingSphere::MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r)
{ {
MathLib::Vector3 const a(p,r); MathLib::Vector3 const a(p,r);
MathLib::Vector3 const b(p,q); MathLib::Vector3 const b(p,q);
...@@ -78,17 +62,17 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G ...@@ -78,17 +62,17 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
} }
else else
{ {
BoundingSphere two_pnts_sphere; MinimalBoundingSphere two_pnts_sphere;
if (a.getLength() > b.getLength()) if (a.getLength() > b.getLength())
two_pnts_sphere = BoundingSphere(p,r); two_pnts_sphere = MinimalBoundingSphere(p,r);
else else
two_pnts_sphere = BoundingSphere(p,q); two_pnts_sphere = MinimalBoundingSphere(p,q);
_radius = two_pnts_sphere.getRadius(); _radius = two_pnts_sphere.getRadius();
_center = two_pnts_sphere.getCenter(); _center = two_pnts_sphere.getCenter();
} }
} }
BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r, GeoLib::Point const& s) MinimalBoundingSphere::MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r, GeoLib::Point const& s)
{ {
MathLib::Vector3 const a(p, q); MathLib::Vector3 const a(p, q);
MathLib::Vector3 const b(p, r); MathLib::Vector3 const b(p, r);
...@@ -96,10 +80,7 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G ...@@ -96,10 +80,7 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
if (!GeoLib::isCoplanar(p, q, r, s)) if (!GeoLib::isCoplanar(p, q, r, s))
{ {
// det of matrix [a^T, b^T, c^T]^T double const denom = 2.0 * GeoLib::scalarTriple(a,b,c);
double const denom = 2.0 * (a[0] * (b[1] * c[2] - c[1] * b[2])
- b[0] * (a[1] * c[2] - c[1] * a[2])
+ c[0] * (a[1] * b[2] - b[1] * a[2]));
MathLib::Vector3 const o = (scalarProduct(c,c) * crossProduct(a,b) MathLib::Vector3 const o = (scalarProduct(c,c) * crossProduct(a,b)
+ scalarProduct(b,b) * crossProduct(c,a) + scalarProduct(b,b) * crossProduct(c,a)
+ scalarProduct(a,a) * crossProduct(b,c)) + scalarProduct(a,a) * crossProduct(b,c))
...@@ -110,10 +91,10 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G ...@@ -110,10 +91,10 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
} }
else else
{ {
BoundingSphere const pqr(p, q , r); MinimalBoundingSphere const pqr(p, q , r);
BoundingSphere const pqs(p, q , s); MinimalBoundingSphere const pqs(p, q , s);
BoundingSphere const prs(p, r , s); MinimalBoundingSphere const prs(p, r , s);
BoundingSphere const qrs(q, r , s); MinimalBoundingSphere const qrs(q, r , s);
_radius = pqr.getRadius(); _radius = pqr.getRadius();
_center = pqr.getCenter(); _center = pqr.getCenter();
if (_radius < pqs.getRadius()) if (_radius < pqs.getRadius())
...@@ -134,36 +115,34 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G ...@@ -134,36 +115,34 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
} }
} }
BoundingSphere::BoundingSphere(std::vector<GeoLib::Point*> const& points) MinimalBoundingSphere::MinimalBoundingSphere(std::vector<GeoLib::Point*> const& points)
: _center(0,0,0), _radius(-1) : _radius(-1), _center(0,0,0)
{ {
std::size_t const n_points (points.size());
std::vector<GeoLib::Point*> sphere_points(points); std::vector<GeoLib::Point*> sphere_points(points);
MinimalBoundingSphere const bounding_sphere = recurseCalculation(sphere_points, 0, sphere_points.size(), 0);
BoundingSphere const bounding_sphere = recurseCalculation(sphere_points, 0, sphere_points.size(), 0);
_center = bounding_sphere.getCenter(); _center = bounding_sphere.getCenter();
_radius = bounding_sphere.getRadius(); _radius = bounding_sphere.getRadius();
} }
BoundingSphere BoundingSphere::recurseCalculation(std::vector<GeoLib::Point*> sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points) MinimalBoundingSphere MinimalBoundingSphere::recurseCalculation(std::vector<GeoLib::Point*> sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points)
{ {
BoundingSphere sphere; MinimalBoundingSphere sphere;
switch(n_boundary_points) switch(n_boundary_points)
{ {
case 0: case 0:
sphere = BoundingSphere(); sphere = MinimalBoundingSphere();
break; break;
case 1: case 1:
sphere = BoundingSphere(*sphere_points[start_idx-1]); sphere = MinimalBoundingSphere(*sphere_points[start_idx-1]);
break; break;
case 2: case 2:
sphere = BoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2]); sphere = MinimalBoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2]);
break; break;
case 3: case 3:
sphere = BoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2], *sphere_points[start_idx-3]); sphere = MinimalBoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2], *sphere_points[start_idx-3]);
break; break;
case 4: case 4:
sphere = BoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2], *sphere_points[start_idx-3], *sphere_points[start_idx-4]); sphere = MinimalBoundingSphere(*sphere_points[start_idx-1], *sphere_points[start_idx-2], *sphere_points[start_idx-3], *sphere_points[start_idx-4]);
return sphere; return sphere;
} }
...@@ -184,12 +163,12 @@ BoundingSphere BoundingSphere::recurseCalculation(std::vector<GeoLib::Point*> sp ...@@ -184,12 +163,12 @@ BoundingSphere BoundingSphere::recurseCalculation(std::vector<GeoLib::Point*> sp
return sphere; return sphere;
} }
double BoundingSphere::pointDistanceSquared(GeoLib::Point const& pnt) const double MinimalBoundingSphere::pointDistanceSquared(GeoLib::Point const& pnt) const
{ {
return MathLib::sqrDist(_center.getCoords(), pnt.getCoords())-(_radius*_radius); return MathLib::sqrDist(_center.getCoords(), pnt.getCoords())-(_radius*_radius);
} }
std::vector<GeoLib::Point*>* BoundingSphere::getRandomSpherePoints(std::size_t n_points) const std::vector<GeoLib::Point*>* MinimalBoundingSphere::getRandomSpherePoints(std::size_t n_points) const
{ {
std::vector<GeoLib::Point*> *pnts = new std::vector<GeoLib::Point*>; std::vector<GeoLib::Point*> *pnts = new std::vector<GeoLib::Point*>;
pnts->reserve(n_points); pnts->reserve(n_points);
......
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
* \file Calculation of a minimum bounding sphere for a vector of points * \file Calculation of a minimum bounding sphere for a vector of points
* \author Karsten Rink * \author Karsten Rink
* \date 2014-07-11 * \date 2014-07-11
* \brief Definition of the BoundingSphere class. * \brief Definition of the MinimalBoundingSphere class.
* *
* \copyright * \copyright
* Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License. * Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or * See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license * http://www.opengeosys.org/project/license
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
* *
*/ */
#ifndef BOUNDINGSPHERE_H_ #ifndef MINIMALBOUNDINGSPHERE_H_
#define BOUNDINGSPHERE_H_ #define MINIMALBOUNDINGSPHERE_H_
#include <vector> #include <vector>
...@@ -24,28 +24,25 @@ ...@@ -24,28 +24,25 @@
namespace GeoLib namespace GeoLib
{ {
class BoundingSphere /**
* Calculated center and radius of a minimal bounding sphere for a given number of geometric points.
*/
class MinimalBoundingSphere
{ {
public: public:
/// Constructor using no points
BoundingSphere();
/// Copy constructor /// Copy constructor
BoundingSphere(BoundingSphere const& sphere); MinimalBoundingSphere(MinimalBoundingSphere const& sphere) = default;
/// Move constructor
BoundingSphere(BoundingSphere const&& sphere);
/// Point-Sphere /// Point-Sphere
BoundingSphere(GeoLib::Point const& p); MinimalBoundingSphere(GeoLib::Point const& p, double radius = std::numeric_limits<double>::epsilon());
/// Constructor using center and radius
BoundingSphere(GeoLib::Point const& p, double radius);
/// Bounding sphere using two points /// Bounding sphere using two points
BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q); MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q);
/// Bounding sphere using three points /// Bounding sphere using three points
BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r); MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r);
/// Bounding sphere using four points /// Bounding sphere using four points
BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r, GeoLib::Point const& s); MinimalBoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, GeoLib::Point const& r, GeoLib::Point const& s);
/// Bounding sphere of n points /// Bounding sphere of n points
BoundingSphere(std::vector<GeoLib::Point*> const& points); MinimalBoundingSphere(std::vector<GeoLib::Point*> const& points);
~BoundingSphere() {} ~MinimalBoundingSphere() {}
/// Returns the center point of the sphere /// Returns the center point of the sphere
GeoLib::Point getCenter() const { return GeoLib::Point(_center.getCoords()); } GeoLib::Point getCenter() const { return GeoLib::Point(_center.getCoords()); }
...@@ -60,6 +57,9 @@ public: ...@@ -60,6 +57,9 @@ public:
std::vector<GeoLib::Point*>* getRandomSpherePoints(std::size_t n_points) const; std::vector<GeoLib::Point*>* getRandomSpherePoints(std::size_t n_points) const;
private: private:
/// Constructor using no points
MinimalBoundingSphere();
/** /**
* Recursive method for calculating a minimal bounding sphere for an arbitrary number of points. * Recursive method for calculating a minimal bounding sphere for an arbitrary number of points.
* Note: This method will change the order of elements in the vector sphere_points. * Note: This method will change the order of elements in the vector sphere_points.
...@@ -70,10 +70,10 @@ private: ...@@ -70,10 +70,10 @@ private:
* *
* Algorithm based the following two papers: * Algorithm based the following two papers:
* Emo Welzl: Smallest enclosing disks (balls and ellipsoids). New Results and New Trends in Computer Science, pp. 359--370, 1991 * Emo Welzl: Smallest enclosing disks (balls and ellipsoids). New Results and New Trends in Computer Science, pp. 359--370, 1991
* Bernd Gärtner: Fast and Robust Smallest Enclosing Balls. ESA99, pp. 325--338, 1999. * Bernd Gaertner: Fast and Robust Smallest Enclosing Balls. ESA99, pp. 325--338, 1999.
* Code based on "Smallest Enclosing Spheres" implementation by Nicolas Capens on flipcode's Developer Toolbox (www.flipcode.com) * Code based on "Smallest Enclosing Spheres" implementation by Nicolas Capens on flipcode's Developer Toolbox (www.flipcode.com)
*/ */
static BoundingSphere recurseCalculation(std::vector<GeoLib::Point*> sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points); static MinimalBoundingSphere recurseCalculation(std::vector<GeoLib::Point*> sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points);
double _radius; double _radius;
MathLib::Vector3 _center; MathLib::Vector3 _center;
...@@ -81,4 +81,4 @@ private: ...@@ -81,4 +81,4 @@ private:
} // namespace } // namespace
#endif /* BOUNDINGSPHERE_H_ */ #endif /* MINIMALBOUNDINGSPHERE_H_ */
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* \date 2014-08-29 * \date 2014-08-29
* *
* \copyright * \copyright
* Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org) * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License. * Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or * See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license * http://www.opengeosys.org/project/license
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "GeoLib/BoundingSphere.h" #include "GeoLib/MinimalBoundingSphere.h"
#include "GeoLib/Point.h" #include "GeoLib/Point.h"
TEST(GeoLib, TestBoundingSphere) TEST(GeoLib, TestBoundingSphere)
...@@ -40,7 +40,7 @@ TEST(GeoLib, TestBoundingSphere) ...@@ -40,7 +40,7 @@ TEST(GeoLib, TestBoundingSphere)
* Tests if a smaller number of points than available is used if the resulting sphere is smaller. * Tests if a smaller number of points than available is used if the resulting sphere is smaller.
* Expected result is C=(1,0,0), r=1 * Expected result is C=(1,0,0), r=1
*/ */
GeoLib::BoundingSphere s(pnts); GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter(); GeoLib::Point center = s.getCenter();
ASSERT_NEAR(1.0, center[0], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(1.0, center[0], std::numeric_limits<double>::epsilon());
ASSERT_NEAR(0.0, center[1], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(0.0, center[1], std::numeric_limits<double>::epsilon());
...@@ -62,7 +62,7 @@ TEST(GeoLib, TestBoundingSphere) ...@@ -62,7 +62,7 @@ TEST(GeoLib, TestBoundingSphere)
* Expected result is C=(1,0.0246,-0.3446), r=1.058 * Expected result is C=(1,0.0246,-0.3446), r=1.058
*/ */
(*pnts[2])[2] -= 1.4; (*pnts[2])[2] -= 1.4;
GeoLib::BoundingSphere s(pnts); GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter(); GeoLib::Point center = s.getCenter();
ASSERT_NEAR(1.0, center[0], 0.0001); ASSERT_NEAR(1.0, center[0], 0.0001);
ASSERT_NEAR(0.0246, center[1], 0.0001); ASSERT_NEAR(0.0246, center[1], 0.0001);
...@@ -84,7 +84,7 @@ TEST(GeoLib, TestBoundingSphere) ...@@ -84,7 +84,7 @@ TEST(GeoLib, TestBoundingSphere)
* A "cube" where one node is pushed slightly towards the centre (and should be ignored). * A "cube" where one node is pushed slightly towards the centre (and should be ignored).
* Expected result is C=(0.5,0.5,0.5), r=0.866 * Expected result is C=(0.5,0.5,0.5), r=0.866
*/ */
GeoLib::BoundingSphere s(pnts); GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter(); GeoLib::Point center = s.getCenter();
ASSERT_NEAR(0.5, center[0], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(0.5, center[0], std::numeric_limits<double>::epsilon());
ASSERT_NEAR(0.5, center[1], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(0.5, center[1], std::numeric_limits<double>::epsilon());
...@@ -98,7 +98,7 @@ TEST(GeoLib, TestBoundingSphere) ...@@ -98,7 +98,7 @@ TEST(GeoLib, TestBoundingSphere)
* Expected result is C=(0.5,0.5,0.6), r=0.9273 * Expected result is C=(0.5,0.5,0.6), r=0.9273
*/ */
(*pnts[7])[2] += 0.3; (*pnts[7])[2] += 0.3;
GeoLib::BoundingSphere s(pnts); GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter(); GeoLib::Point center = s.getCenter();
ASSERT_NEAR(0.5, center[0], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(0.5, center[0], std::numeric_limits<double>::epsilon());
ASSERT_NEAR(0.5, center[1], std::numeric_limits<double>::epsilon()); ASSERT_NEAR(0.5, center[1], std::numeric_limits<double>::epsilon());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment