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 @@
* \file Calculation of a minimum bounding sphere for a vector of points
* \author Karsten Rink
* \date 2014-07-11
* \brief Implementation of the BoundingSphere class.
* \brief Implementation of the MinimalBoundingSphere class.
*
* \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.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "BoundingSphere.h"
#include "MinimalBoundingSphere.h"
#include <ctime>
......@@ -21,33 +21,17 @@
namespace GeoLib {
BoundingSphere::BoundingSphere()
MinimalBoundingSphere::MinimalBoundingSphere()
: _radius(-1), _center(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max())
{
}
BoundingSphere::BoundingSphere(BoundingSphere const& sphere)
: _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)
MinimalBoundingSphere::MinimalBoundingSphere(GeoLib::Point const& p, double radius)
: _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)
{
MathLib::Vector3 const a(p, 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 b(p,q);
......@@ -78,17 +62,17 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
}
else
{
BoundingSphere two_pnts_sphere;
MinimalBoundingSphere two_pnts_sphere;
if (a.getLength() > b.getLength())
two_pnts_sphere = BoundingSphere(p,r);
two_pnts_sphere = MinimalBoundingSphere(p,r);
else
two_pnts_sphere = BoundingSphere(p,q);
two_pnts_sphere = MinimalBoundingSphere(p,q);
_radius = two_pnts_sphere.getRadius();
_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 b(p, r);
......@@ -96,10 +80,7 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
if (!GeoLib::isCoplanar(p, q, r, s))
{
// det of matrix [a^T, b^T, c^T]^T
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]));
double const denom = 2.0 * GeoLib::scalarTriple(a,b,c);
MathLib::Vector3 const o = (scalarProduct(c,c) * crossProduct(a,b)
+ scalarProduct(b,b) * crossProduct(c,a)
+ scalarProduct(a,a) * crossProduct(b,c))
......@@ -110,10 +91,10 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
}
else
{
BoundingSphere const pqr(p, q , r);
BoundingSphere const pqs(p, q , s);
BoundingSphere const prs(p, r , s);
BoundingSphere const qrs(q, r , s);
MinimalBoundingSphere const pqr(p, q , r);
MinimalBoundingSphere const pqs(p, q , s);
MinimalBoundingSphere const prs(p, r , s);
MinimalBoundingSphere const qrs(q, r , s);
_radius = pqr.getRadius();
_center = pqr.getCenter();
if (_radius < pqs.getRadius())
......@@ -134,36 +115,34 @@ BoundingSphere::BoundingSphere(GeoLib::Point const& p, GeoLib::Point const& q, G
}
}
BoundingSphere::BoundingSphere(std::vector<GeoLib::Point*> const& points)
: _center(0,0,0), _radius(-1)
MinimalBoundingSphere::MinimalBoundingSphere(std::vector<GeoLib::Point*> const& points)
: _radius(-1), _center(0,0,0)
{
std::size_t const n_points (points.size());
std::vector<GeoLib::Point*> sphere_points(points);
BoundingSphere const bounding_sphere = recurseCalculation(sphere_points, 0, sphere_points.size(), 0);
MinimalBoundingSphere const bounding_sphere = recurseCalculation(sphere_points, 0, sphere_points.size(), 0);
_center = bounding_sphere.getCenter();
_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)
{
case 0:
sphere = BoundingSphere();
sphere = MinimalBoundingSphere();
break;
case 1:
sphere = BoundingSphere(*sphere_points[start_idx-1]);
sphere = MinimalBoundingSphere(*sphere_points[start_idx-1]);
break;
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;
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;
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;
}
......@@ -184,12 +163,12 @@ BoundingSphere BoundingSphere::recurseCalculation(std::vector<GeoLib::Point*> sp
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);
}
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*>;
pnts->reserve(n_points);
......
......@@ -2,10 +2,10 @@
* \file Calculation of a minimum bounding sphere for a vector of points
* \author Karsten Rink
* \date 2014-07-11
* \brief Definition of the BoundingSphere class.
* \brief Definition of the MinimalBoundingSphere class.
*
* \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.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
......@@ -13,8 +13,8 @@
*
*/
#ifndef BOUNDINGSPHERE_H_
#define BOUNDINGSPHERE_H_
#ifndef MINIMALBOUNDINGSPHERE_H_
#define MINIMALBOUNDINGSPHERE_H_
#include <vector>
......@@ -24,28 +24,25 @@
namespace GeoLib
{
class BoundingSphere
/**
* Calculated center and radius of a minimal bounding sphere for a given number of geometric points.
*/
class MinimalBoundingSphere
{
public:
/// Constructor using no points
BoundingSphere();
/// Copy constructor
BoundingSphere(BoundingSphere const& sphere);
/// Move constructor
BoundingSphere(BoundingSphere const&& sphere);
MinimalBoundingSphere(MinimalBoundingSphere const& sphere) = default;
/// Point-Sphere
BoundingSphere(GeoLib::Point const& p);
/// Constructor using center and radius
BoundingSphere(GeoLib::Point const& p, double radius);
MinimalBoundingSphere(GeoLib::Point const& p, double radius = std::numeric_limits<double>::epsilon());
/// 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
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
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
BoundingSphere(std::vector<GeoLib::Point*> const& points);
~BoundingSphere() {}
MinimalBoundingSphere(std::vector<GeoLib::Point*> const& points);
~MinimalBoundingSphere() {}
/// Returns the center point of the sphere
GeoLib::Point getCenter() const { return GeoLib::Point(_center.getCoords()); }
......@@ -60,6 +57,9 @@ public:
std::vector<GeoLib::Point*>* getRandomSpherePoints(std::size_t n_points) const;
private:
/// Constructor using no points
MinimalBoundingSphere();
/**
* 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.
......@@ -70,10 +70,10 @@ private:
*
* 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
* 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)
*/
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;
MathLib::Vector3 _center;
......@@ -81,4 +81,4 @@ private:
} // namespace
#endif /* BOUNDINGSPHERE_H_ */
#endif /* MINIMALBOUNDINGSPHERE_H_ */
......@@ -4,7 +4,7 @@
* \date 2014-08-29
*
* \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.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
......@@ -14,7 +14,7 @@
#include "gtest/gtest.h"
#include "GeoLib/BoundingSphere.h"
#include "GeoLib/MinimalBoundingSphere.h"
#include "GeoLib/Point.h"
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.
* Expected result is C=(1,0,0), r=1
*/
GeoLib::BoundingSphere s(pnts);
GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter();
ASSERT_NEAR(1.0, center[0], std::numeric_limits<double>::epsilon());
ASSERT_NEAR(0.0, center[1], std::numeric_limits<double>::epsilon());
......@@ -62,7 +62,7 @@ TEST(GeoLib, TestBoundingSphere)
* Expected result is C=(1,0.0246,-0.3446), r=1.058
*/
(*pnts[2])[2] -= 1.4;
GeoLib::BoundingSphere s(pnts);
GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter();
ASSERT_NEAR(1.0, center[0], 0.0001);
ASSERT_NEAR(0.0246, center[1], 0.0001);
......@@ -84,7 +84,7 @@ TEST(GeoLib, TestBoundingSphere)
* 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
*/
GeoLib::BoundingSphere s(pnts);
GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter();
ASSERT_NEAR(0.5, center[0], std::numeric_limits<double>::epsilon());
ASSERT_NEAR(0.5, center[1], std::numeric_limits<double>::epsilon());
......@@ -98,7 +98,7 @@ TEST(GeoLib, TestBoundingSphere)
* Expected result is C=(0.5,0.5,0.6), r=0.9273
*/
(*pnts[7])[2] += 0.3;
GeoLib::BoundingSphere s(pnts);
GeoLib::MinimalBoundingSphere s(pnts);
GeoLib::Point center = s.getCenter();
ASSERT_NEAR(0.5, center[0], 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