OGS
GeoLib::MinimalBoundingSphere Class Referencefinal

Detailed Description

Calculated center and radius of a minimal bounding sphere for a given number of geometric points.

Definition at line 17 of file MinimalBoundingSphere.h.

#include <MinimalBoundingSphere.h>

Collaboration diagram for GeoLib::MinimalBoundingSphere:
[legend]

Public Member Functions

 MinimalBoundingSphere (MathLib::Point3d const &p, double radius=std::numeric_limits< double >::epsilon())
 Point-Sphere.
 MinimalBoundingSphere (MathLib::Point3d const &p, MathLib::Point3d const &q)
 Bounding sphere using two points.
 MinimalBoundingSphere (MathLib::Point3d const &p, MathLib::Point3d const &q, MathLib::Point3d const &r)
 Bounding sphere using three points.
 MinimalBoundingSphere (MathLib::Point3d const &p, MathLib::Point3d const &q, MathLib::Point3d const &r, MathLib::Point3d const &s)
 Bounding sphere using four points.
 MinimalBoundingSphere (std::vector< MathLib::Point3d * > const &points)
 Bounding sphere of n points.
MathLib::Point3d getCenter () const
 Returns the center point of the sphere.
double getRadius () const
 Returns the radius of the sphere.
double pointDistanceSquared (MathLib::Point3d const &pnt) const

Private Member Functions

 MinimalBoundingSphere ()
 Constructor using no points.

Static Private Member Functions

static MinimalBoundingSphere recurseCalculation (std::vector< MathLib::Point3d * > sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points)

Private Attributes

double _radius {-1}
MathLib::Point3d _center

Constructor & Destructor Documentation

◆ MinimalBoundingSphere() [1/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( MathLib::Point3d const & p,
double radius = std::numeric_limits<double>::epsilon() )
explicit

◆ MinimalBoundingSphere() [2/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( MathLib::Point3d const & p,
MathLib::Point3d const & q )

Bounding sphere using two points.

Definition at line 23 of file MinimalBoundingSphere.cpp.

25 : _radius(std::numeric_limits<double>::epsilon()), _center(p)
26{
27 Eigen::Vector3d const a = q.asEigenVector3d() - p.asEigenVector3d();
28
29 Eigen::Vector3d o = a / 2;
30 _radius = o.norm() + std::numeric_limits<double>::epsilon();
31 o += p.asEigenVector3d();
32 _center = MathLib::Point3d{{o[0], o[1], o[2]}};
33}
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55

References _center, _radius, and MathLib::Point3d::asEigenVector3d().

◆ MinimalBoundingSphere() [3/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( MathLib::Point3d const & p,
MathLib::Point3d const & q,
MathLib::Point3d const & r )

Bounding sphere using three points.

Definition at line 35 of file MinimalBoundingSphere.cpp.

38{
39 auto const& vp = p.asEigenVector3d();
40 Eigen::Vector3d const a = r.asEigenVector3d() - vp;
41 Eigen::Vector3d const b = q.asEigenVector3d() - vp;
42 Eigen::Vector3d const axb = a.cross(b);
43
44 if (axb.squaredNorm() > 0)
45 {
46 double const denom = 2.0 * axb.dot(axb);
47 Eigen::Vector3d o =
48 (b.dot(b) * axb.cross(a) + a.dot(a) * b.cross(axb)) / denom;
49 _radius = o.norm() + std::numeric_limits<double>::epsilon();
50 o += vp;
51 _center = MathLib::Point3d{{o[0], o[1], o[2]}};
52 }
53 else
54 {
55 MinimalBoundingSphere two_pnts_sphere;
56 if (a.squaredNorm() > b.squaredNorm())
57 {
58 two_pnts_sphere = MinimalBoundingSphere(p, r);
59 }
60 else
61 {
62 two_pnts_sphere = MinimalBoundingSphere(p, q);
63 }
64 _radius = two_pnts_sphere.getRadius();
65 _center = two_pnts_sphere.getCenter();
66 }
67}
MinimalBoundingSphere(MathLib::Point3d const &p, double radius=std::numeric_limits< double >::epsilon())
Point-Sphere.
MinimalBoundingSphere()
Constructor using no points.

References MinimalBoundingSphere(), _center, _radius, MathLib::Point3d::asEigenVector3d(), getCenter(), and getRadius().

◆ MinimalBoundingSphere() [4/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( MathLib::Point3d const & p,
MathLib::Point3d const & q,
MathLib::Point3d const & r,
MathLib::Point3d const & s )

Bounding sphere using four points.

Definition at line 69 of file MinimalBoundingSphere.cpp.

73{
74 Eigen::Vector3d const va = q.asEigenVector3d() - p.asEigenVector3d();
75 Eigen::Vector3d const vb = r.asEigenVector3d() - p.asEigenVector3d();
76 Eigen::Vector3d const vc = s.asEigenVector3d() - p.asEigenVector3d();
77
78 if (!MathLib::isCoplanar(p, q, r, s))
79 {
80 double const denom = 2.0 * va.cross(vb).dot(vc);
81 Eigen::Vector3d o =
82 (vc.dot(vc) * va.cross(vb) + vb.dot(vb) * vc.cross(va) +
83 va.dot(va) * vb.cross(vc)) /
84 denom;
85
86 _radius = o.norm() + std::numeric_limits<double>::epsilon();
87 o += p.asEigenVector3d();
88 _center = MathLib::Point3d({o[0], o[1], o[2]});
89 }
90 else
91 {
92 MinimalBoundingSphere const pqr(p, q, r);
93 MinimalBoundingSphere const pqs(p, q, s);
94 MinimalBoundingSphere const prs(p, r, s);
95 MinimalBoundingSphere const qrs(q, r, s);
96 _radius = pqr.getRadius();
97 _center = pqr.getCenter();
98 if (_radius < pqs.getRadius())
99 {
100 _radius = pqs.getRadius();
101 _center = pqs.getCenter();
102 }
103 if (_radius < prs.getRadius())
104 {
105 _radius = prs.getRadius();
106 _center = prs.getCenter();
107 }
108 if (_radius < qrs.getRadius())
109 {
110 _radius = qrs.getRadius();
111 _center = qrs.getCenter();
112 }
113 }
114}
bool isCoplanar(const MathLib::Point3d &a, const MathLib::Point3d &b, const MathLib::Point3d &c, const MathLib::Point3d &d)
Checks if the four given points are located on a plane.

References MinimalBoundingSphere(), _center, _radius, MathLib::Point3d::asEigenVector3d(), getCenter(), getRadius(), and MathLib::isCoplanar().

◆ MinimalBoundingSphere() [5/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( std::vector< MathLib::Point3d * > const & points)
explicit

Bounding sphere of n points.

Definition at line 116 of file MinimalBoundingSphere.cpp.

118 : _radius(-1), _center({0, 0, 0})
119{
120 const std::vector<MathLib::Point3d*>& sphere_points(points);
121 MinimalBoundingSphere const bounding_sphere =
122 recurseCalculation(sphere_points, 0, sphere_points.size(), 0);
123 _center = bounding_sphere.getCenter();
124 _radius = bounding_sphere.getRadius();
125}
static MinimalBoundingSphere recurseCalculation(std::vector< MathLib::Point3d * > sphere_points, std::size_t start_idx, std::size_t length, std::size_t n_boundary_points)

References MinimalBoundingSphere(), _center, and _radius.

◆ MinimalBoundingSphere() [6/6]

GeoLib::MinimalBoundingSphere::MinimalBoundingSphere ( )
privatedefault

Constructor using no points.

References MinimalBoundingSphere().

Referenced by recurseCalculation().

Member Function Documentation

◆ getCenter()

MathLib::Point3d GeoLib::MinimalBoundingSphere::getCenter ( ) const
inline

Returns the center point of the sphere.

Definition at line 39 of file MinimalBoundingSphere.h.

39{ return _center; }

References _center.

Referenced by MinimalBoundingSphere(), and MinimalBoundingSphere().

◆ getRadius()

double GeoLib::MinimalBoundingSphere::getRadius ( ) const
inline

Returns the radius of the sphere.

Definition at line 42 of file MinimalBoundingSphere.h.

42{ return _radius; }

References _radius.

Referenced by MinimalBoundingSphere(), MinimalBoundingSphere(), and MeshToolsLib::RadiusEdgeRatioMetric::calculateQuality().

◆ pointDistanceSquared()

double GeoLib::MinimalBoundingSphere::pointDistanceSquared ( MathLib::Point3d const & pnt) const

Returns the squared euclidean distance of a point from the sphere (for points within the sphere distance is negative)

Definition at line 183 of file MinimalBoundingSphere.cpp.

185{
186 return MathLib::sqrDist(_center, pnt) - (_radius * _radius);
187}
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19

References _center, _radius, and MathLib::sqrDist().

Referenced by recurseCalculation().

◆ recurseCalculation()

MinimalBoundingSphere GeoLib::MinimalBoundingSphere::recurseCalculation ( std::vector< MathLib::Point3d * > sphere_points,
std::size_t start_idx,
std::size_t length,
std::size_t n_boundary_points )
staticprivate

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.

Parameters
sphere_pointsThe vector of points for which the smallest enclosing sphere is calculated
start_idxStart index of the vector subrange analysed in the current recursive step
lengthLength of the vector subrange analysed in the current recursive step
n_boundary_pointsNumber of found boundary points in the current recursive step

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 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)

Definition at line 127 of file MinimalBoundingSphere.cpp.

132{
134 switch (n_boundary_points)
135 {
136 case 0:
137 sphere = MinimalBoundingSphere();
138 break;
139 case 1:
140 sphere = MinimalBoundingSphere(*sphere_points[start_idx - 1]);
141 break;
142 case 2:
143 sphere = MinimalBoundingSphere(*sphere_points[start_idx - 1],
144 *sphere_points[start_idx - 2]);
145 break;
146 case 3:
147 sphere = MinimalBoundingSphere(*sphere_points[start_idx - 1],
148 *sphere_points[start_idx - 2],
149 *sphere_points[start_idx - 3]);
150 break;
151 case 4:
152 sphere = MinimalBoundingSphere(
153 *sphere_points[start_idx - 1], *sphere_points[start_idx - 2],
154 *sphere_points[start_idx - 3], *sphere_points[start_idx - 4]);
155 return sphere;
156 }
157
158 for (std::size_t i = 0; i < length; ++i)
159 {
160 // current point is located outside of sphere
161 if (sphere.pointDistanceSquared(*sphere_points[start_idx + i]) > 0)
162 {
163 if (i > start_idx)
164 {
165 using DiffType =
166 std::vector<MathLib::Point3d*>::iterator::difference_type;
167 std::vector<MathLib::Point3d*> const tmp_ps(
168 sphere_points.cbegin() + static_cast<DiffType>(start_idx),
169 sphere_points.cbegin() +
170 static_cast<DiffType>(start_idx + i + 1));
171 std::copy(tmp_ps.cbegin(), --tmp_ps.cend(),
172 sphere_points.begin() +
173 static_cast<DiffType>(start_idx + 1));
174 sphere_points[start_idx] = tmp_ps.back();
175 }
176 sphere = recurseCalculation(sphere_points, start_idx + 1, i,
177 n_boundary_points + 1);
178 }
179 }
180 return sphere;
181}

References MinimalBoundingSphere(), MinimalBoundingSphere(), pointDistanceSquared(), and recurseCalculation().

Referenced by recurseCalculation().

Member Data Documentation

◆ _center

MathLib::Point3d GeoLib::MinimalBoundingSphere::_center
private
Initial value:
{{std::numeric_limits<double>::max(),
std::numeric_limits<double>::max(),
std::numeric_limits<double>::max()}}

Definition at line 76 of file MinimalBoundingSphere.h.

76 {{std::numeric_limits<double>::max(),
77 std::numeric_limits<double>::max(),
78 std::numeric_limits<double>::max()}};

Referenced by MinimalBoundingSphere(), MinimalBoundingSphere(), MinimalBoundingSphere(), MinimalBoundingSphere(), MinimalBoundingSphere(), getCenter(), and pointDistanceSquared().

◆ _radius

double GeoLib::MinimalBoundingSphere::_radius {-1}
private

The documentation for this class was generated from the following files: