Sphere.h
Go to the documentation of this file.
1 #ifndef SPHERE_HEADER
2 #define SPHERE_HEADER
3 #include <stdio.h>
4 
5 #include <istream>
6 #include <ostream>
7 #include <stdexcept>
8 #include <utility>
9 
10 #include "LevMarFitting.h"
11 #include "LevMarLSWeight.h"
12 #include "PointCloud.h"
13 #include "basic.h"
15 #include <MiscLib/NoShrinkVector.h>
16 #include <MiscLib/Vector.h>
17 
18 #ifndef DLL_LINKAGE
19 #define DLL_LINKAGE
20 #endif
21 
22 struct DLL_LINKAGE InvalidTetrahedonError : public std::runtime_error
23 {
25 };
26 
28 {
29 public:
30  enum
31  {
32  RequiredSamples = 2
33  };
34 
35  Sphere();
36  Sphere(const Vec3f& center, float radius);
37  Sphere(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3, const Vec3f& p4);
38  bool Init(const MiscLib::Vector<Vec3f>& samples);
39  bool Init(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3, const Vec3f& p4);
40  bool Init2(const Vec3f& p1, const Vec3f& p2, const Vec3f& n1, const Vec3f& n2);
41  bool Init(bool binary, std::istream* i);
42  void Init(FILE* i);
43  void Init(float* array);
44  inline float Distance(const Vec3f& p) const;
45  inline void Normal(const Vec3f& p, Vec3f* normal) const;
46  inline float DistanceAndNormal(const Vec3f& p, Vec3f* normal) const;
47  inline float SignedDistance(const Vec3f& p) const;
48  void Project(const Vec3f& p, Vec3f* pp) const;
49  const Vec3f& Center() const;
50 
51  void
53  {
54  m_center = center;
55  }
56 
57  float Radius() const;
58 
59  void
60  Radius(float radius)
61  {
62  m_radius = radius;
63  }
64 
65  bool LeastSquaresFit(const PointCloud& pc,
68  template <class IteratorT>
69  bool LeastSquaresFit(IteratorT begin, IteratorT end);
70 
71  bool
72  Fit(const PointCloud& pc,
75  {
76  return LeastSquaresFit(pc, begin, end);
77  }
78 
79  static bool Interpolate(const MiscLib::Vector<Sphere>& spheres,
80  const MiscLib::Vector<float>& weights,
81  Sphere* is);
82  void Serialize(bool binary, std::ostream* o) const;
83  static size_t SerializedSize();
84  void Serialize(FILE* o) const;
85  void Serialize(float* array) const;
86  static size_t SerializedFloatSize();
87 
88  void Transform(float scale, const Vec3f& translate);
89  inline unsigned int
90  Intersect(const Vec3f& p, const Vec3f& r, float* first, float* second) const;
91 
92 private:
93  template <class WeightT>
94  class LevMarSimpleSphere : public WeightT
95  {
96  public:
97  enum
98  {
99  NumParams = 4
100  };
101 
102  typedef float ScalarType;
103 
104  template <class IteratorT>
105  ScalarType
106  Chi(const ScalarType* params,
107  IteratorT begin,
108  IteratorT end,
109  ScalarType* values,
110  ScalarType* temp) const
111  {
112  ScalarType chi = 0;
113  int size = end - begin;
114 #pragma omp parallel for schedule(static) reduction(+ : chi)
115  for (int idx = 0; idx < size; ++idx)
116  {
117  float s = begin[idx][0] - params[0];
118  s *= s;
119  for (unsigned int j = 1; j < 3; ++j)
120  {
121  float ss = begin[idx][j] - params[j];
122  s += ss * ss;
123  }
124  values[idx] = WeightT::Weigh(std::sqrt(s) - params[3]);
125  chi += values[idx] * values[idx];
126  }
127  return chi;
128  }
129 
130  template <class IteratorT>
131  void
132  Derivatives(const ScalarType* params,
133  IteratorT begin,
134  IteratorT end,
135  const ScalarType* values,
136  const ScalarType* temp,
137  ScalarType* matrix) const
138  {
139  int size = end - begin;
140 #pragma omp parallel for schedule(static)
141  for (int idx = 0; idx < size; ++idx)
142  {
143  float s[3];
144  s[0] = begin[idx][0] - params[0];
145  float sl = s[0] * s[0];
146  for (unsigned int i = 1; i < 3; ++i)
147  {
148  s[i] = begin[idx][i] - params[i];
149  sl += s[i] * s[i];
150  }
151  sl = std::sqrt(sl);
152  matrix[idx * NumParams + 0] = -s[0] / sl;
153  matrix[idx * NumParams + 1] = -s[1] / sl;
154  matrix[idx * NumParams + 2] = -s[2] / sl;
155  matrix[idx * NumParams + 3] = -1;
156  WeightT::template DerivWeigh<NumParams>(sl - params[3], matrix + idx * NumParams);
157  }
158  }
159 
160  void
161  Normalize(ScalarType*) const
162  {
163  }
164  };
165 
166  template <class WeightT>
167  class LevMarSphere : public WeightT
168  {
169  public:
170  enum
171  {
172  NumParams = 7
173  };
174 
175  typedef float ScalarType;
176 
177  // parametrization: params[0] - params[2] = normal
178  // params[3] - params[5] = point
179  // params[6] = 1 / radius
180 
181  template <class IteratorT>
182  ScalarType
183  Chi(const ScalarType* params,
184  IteratorT begin,
185  IteratorT end,
186  ScalarType* values,
187  ScalarType* temp) const
188  {
189  ScalarType chi = 0;
190  ScalarType radius = 1 / params[6];
191  Vec3f center = -radius * Vec3f(params[0], params[1], params[2]) +
192  Vec3f(params[3], params[4], params[5]);
193  int size = end - begin;
194 #pragma omp parallel for schedule(static) reduction(+ : chi)
195  for (int idx = 0; idx < size; ++idx)
196  {
197  temp[idx] = (begin[idx] - center).length();
198  chi += (values[idx] = WeightT::Weigh(temp[idx] - radius)) * values[idx];
199  }
200  return chi;
201  }
202 
203  template <class IteratorT>
204  void
205  Derivatives(const ScalarType* params,
206  IteratorT begin,
207  IteratorT end,
208  const ScalarType* values,
209  const ScalarType* temp,
210  ScalarType* matrix) const
211  {
212  Vec3f normal(params[0], params[1], params[2]);
213  Vec3f point(params[3], params[4], params[5]);
214  int size = end - begin;
215 #pragma omp parallel for schedule(static)
216  for (int idx = 0; idx < size; ++idx)
217  {
218  ScalarType denominator = -1.f / temp[idx] * params[6];
219  matrix[idx * NumParams + 0] =
220  (matrix[idx * NumParams + 3] =
221  (point[0] - normal[0] * params[6] - begin[idx][0])) *
222  denominator;
223  matrix[idx * NumParams + 1] =
224  (matrix[idx * NumParams + 4] =
225  (point[1] - normal[1] * params[6] - begin[idx][1])) *
226  denominator;
227  matrix[idx * NumParams + 2] =
228  (matrix[idx * NumParams + 5] =
229  (point[2] - normal[2] * params[6] - begin[idx][2])) *
230  denominator;
231  matrix[idx * NumParams + 3] /= temp[idx];
232  matrix[idx * NumParams + 4] /= temp[idx];
233  matrix[idx * NumParams + 5] /= temp[idx];
234  matrix[idx * NumParams + 6] = (normal[0] * matrix[idx * NumParams + 3] +
235  normal[1] * matrix[idx * NumParams + 4] +
236  normal[2] * matrix[idx * NumParams + 5] + 1) *
237  params[6] * params[6];
238  WeightT::template DerivWeigh<NumParams>(temp[idx] - 1.f / params[6],
239  matrix + idx * NumParams);
240  }
241  }
242 
243  void
244  Normalize(ScalarType* params) const
245  {
246  ScalarType len =
247  std::sqrt(params[0] * params[0] + params[1] * params[1] + params[2] * params[2]);
248  params[0] /= len;
249  params[1] /= len;
250  params[2] /= len;
251  }
252  };
253 
254 private:
255  Vec3f m_center;
256  float m_radius;
257 };
258 
259 inline float
260 Sphere::Distance(const Vec3f& p) const
261 {
262  return abs((m_center - p).length() - m_radius);
263 }
264 
265 inline void
266 Sphere::Normal(const Vec3f& p, Vec3f* normal) const
267 {
268  *normal = p - m_center;
269  normal->normalize();
270 }
271 
272 inline float
273 Sphere::DistanceAndNormal(const Vec3f& p, Vec3f* normal) const
274 {
275  *normal = p - m_center;
276  float l = normal->length();
277  if (l > 0)
278  {
279  *normal /= l;
280  }
281  return abs(l - m_radius);
282 }
283 
284 inline float
286 {
287  return (m_center - p).length() - m_radius;
288 }
289 
290 template <class IteratorT>
291 bool
292 Sphere::LeastSquaresFit(IteratorT begin, IteratorT end)
293 {
294  LevMarSimpleSphere<LevMarLSWeight> levMarSphere;
295  float param[4];
296  for (size_t i = 0; i < 3; ++i)
297  {
298  param[i] = m_center[i];
299  }
300  param[3] = m_radius;
301  if (!LevMar(begin, end, levMarSphere, param))
302  {
303  return false;
304  }
305  for (size_t i = 0; i < 3; ++i)
306  {
307  m_center[i] = param[i];
308  }
309  m_radius = param[3];
310  return true;
311 }
312 
313 inline unsigned int
314 Sphere::Intersect(const Vec3f& p, const Vec3f& r, float* first, float* second) const
315 {
316  using namespace std;
317  Vec3f kDiff = p - m_center;
318  float fA0 = kDiff.dot(kDiff) - m_radius * m_radius;
319  float fA1, fDiscr, fRoot;
320  if (fA0 <= 0)
321  {
322  // P is inside the sphere
323  fA1 = r.dot(kDiff);
324  fDiscr = fA1 * fA1 - fA0;
325  fRoot = sqrt(fDiscr);
326  *first = -fA1 + fRoot;
327  return 1;
328  }
329  // else: P is outside the sphere
330  fA1 = r.dot(kDiff);
331  if (fA1 >= 0)
332  {
333  return 0;
334  }
335  fDiscr = fA1 * fA1 - fA0;
336  if (fDiscr < 0)
337  {
338  return 0;
339  }
340  else if (fDiscr >= /* zero tolerance eps */ 1e-7f)
341  {
342  fRoot = sqrt(fDiscr);
343  *first = -fA1 - fRoot;
344  *second = -fA1 + fRoot;
345  return 2;
346  }
347  *first = -fA1;
348  return 1;
349 }
350 
352 {
353 public:
355  {
356  }
357 
358  SphereAsSquaresParametrization(const Sphere& sphere, const Vec3f& planeNormal);
359  void Init(const Sphere& sphere, const Vec3f& planeNormal);
360 
361  // returns < 0 if point is on lower hemisphere
362  float Parameters(const Vec3f& p, std::pair<float, float>* param) const;
363  bool InSpace(const std::pair<float, float>& param, bool lower, Vec3f* p) const;
364  bool InSpace(const std::pair<float, float>& param, bool lower, Vec3f* p, Vec3f* n) const;
365  void Transform(const GfxTL::MatrixXX<3, 3, float>& rot, const GfxTL::Vector3Df& trans);
366  void HyperplaneCoordinateSystem(Vec3f* hcs0, Vec3f* hcs1, Vec3f* hcs2) const;
367 
368 private:
369  void Hemisphere2Disk(const Vec3f& p, std::pair<float, float>* inDisk) const;
370  void Disk2Square(const std::pair<float, float>& inDisk,
371  std::pair<float, float>* inSquare) const;
372  void Square2Disk(const std::pair<float, float>& inSquare,
373  std::pair<float, float>* inDisk) const;
374  void Disk2Hemisphere(const std::pair<float, float>& inDisk, Vec3f* p) const;
375 
376 private:
377  Sphere m_sphere;
378  Vec3f m_planeNormal;
380 };
381 
383 {
384 public:
386  {
387  }
388 
391  {
392  }
393 
394  bool
395  InSpace(const std::pair<float, float>& param, Vec3f* p) const
396  {
397  return SphereAsSquaresParametrization::InSpace(param, false, p);
398  }
399 
400  bool
401  InSpace(const std::pair<float, float>& param, Vec3f* p, Vec3f* n) const
402  {
403  return SphereAsSquaresParametrization::InSpace(param, false, p, n);
404  }
405 
406  bool
407  InSpace(float u, float v, Vec3f* p) const
408  {
409  return SphereAsSquaresParametrization::InSpace(std::make_pair(u, v), false, p);
410  }
411 
412  bool
413  InSpace(float u, float v, Vec3f* p, Vec3f* n) const
414  {
415  return SphereAsSquaresParametrization::InSpace(std::make_pair(u, v), false, p, n);
416  }
417 };
418 
420 {
421 public:
423  {
424  }
425 
428  {
429  }
430 
431  bool
432  InSpace(const std::pair<float, float>& param, Vec3f* p) const
433  {
434  return SphereAsSquaresParametrization::InSpace(param, true, p);
435  }
436 
437  bool
438  InSpace(const std::pair<float, float>& param, Vec3f* p, Vec3f* n) const
439  {
440  return SphereAsSquaresParametrization::InSpace(param, true, p, n);
441  }
442 
443  bool
444  InSpace(float u, float v, Vec3f* p) const
445  {
446  return SphereAsSquaresParametrization::InSpace(std::make_pair(u, v), true, p);
447  }
448 
449  bool
450  InSpace(float u, float v, Vec3f* p, Vec3f* n) const
451  {
452  return SphereAsSquaresParametrization::InSpace(std::make_pair(u, v), true, p, n);
453  }
454 };
455 
456 #endif
GfxTL::HyperplaneCoordinateSystem< float, 3 >
GfxTL::VectorXD
Definition: MatrixXX.h:24
UpperSphereAsSquaresParametrization::UpperSphereAsSquaresParametrization
UpperSphereAsSquaresParametrization()
Definition: Sphere.h:385
GfxTL::Vec3f
VectorXD< 3, float > Vec3f
Definition: VectorXD.h:733
Vector.h
Vec3f::normalize
float normalize()
Definition: basic.h:141
Vec3f
Definition: basic.h:17
SphereAsSquaresParametrization
Definition: Sphere.h:351
LowerSphereAsSquaresParametrization::LowerSphereAsSquaresParametrization
LowerSphereAsSquaresParametrization(const SphereAsSquaresParametrization &p)
Definition: Sphere.h:426
Sphere::Distance
float Distance(const Vec3f &p) const
Definition: Sphere.h:260
UpperSphereAsSquaresParametrization::InSpace
bool InSpace(float u, float v, Vec3f *p, Vec3f *n) const
Definition: Sphere.h:413
UpperSphereAsSquaresParametrization::UpperSphereAsSquaresParametrization
UpperSphereAsSquaresParametrization(const SphereAsSquaresParametrization &p)
Definition: Sphere.h:389
armarx::view_selection::skills::direction::state::Center
constexpr std::uint8_t Center
Definition: LookDirection.h:50
SphereAsSquaresParametrization::InSpace
bool InSpace(const std::pair< float, float > &param, bool lower, Vec3f *p) const
Definition: Sphere.cpp:509
ProsthesisInterface.values
values
Definition: ProsthesisInterface.py:190
Vec3f::length
float length() const
Definition: basic.h:135
armarx::skills::gui::Parameters
aron::data::DictPtr Parameters
Definition: SkillManagerWrapper.h:21
GfxTL::MatrixXX
Definition: MatrixXX.h:28
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:418
MiscLib::Vector
Definition: Vector.h:19
LowerSphereAsSquaresParametrization::InSpace
bool InSpace(const std::pair< float, float > &param, Vec3f *p) const
Definition: Sphere.h:432
LowerSphereAsSquaresParametrization::LowerSphereAsSquaresParametrization
LowerSphereAsSquaresParametrization()
Definition: Sphere.h:422
LevMarFitting.h
LowerSphereAsSquaresParametrization::InSpace
bool InSpace(const std::pair< float, float > &param, Vec3f *p, Vec3f *n) const
Definition: Sphere.h:438
InvalidTetrahedonError
Definition: Sphere.h:22
UpperSphereAsSquaresParametrization
Definition: Sphere.h:382
Sphere::Fit
bool Fit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition: Sphere.h:72
NoShrinkVector.h
UpperSphereAsSquaresParametrization::InSpace
bool InSpace(const std::pair< float, float > &param, Vec3f *p) const
Definition: Sphere.h:395
armarx::abs
std::vector< T > abs(const std::vector< T > &v)
Definition: VectorHelpers.h:281
UpperSphereAsSquaresParametrization::InSpace
bool InSpace(const std::pair< float, float > &param, Vec3f *p, Vec3f *n) const
Definition: Sphere.h:401
LowerSphereAsSquaresParametrization
Definition: Sphere.h:419
Sphere::Intersect
unsigned int Intersect(const Vec3f &p, const Vec3f &r, float *first, float *second) const
Definition: Sphere.h:314
Sphere::Center
void Center(const Vec3f &center)
Definition: Sphere.h:52
HyperplaneCoordinateSystem.h
LowerSphereAsSquaresParametrization::InSpace
bool InSpace(float u, float v, Vec3f *p) const
Definition: Sphere.h:444
LowerSphereAsSquaresParametrization::InSpace
bool InSpace(float u, float v, Vec3f *p, Vec3f *n) const
Definition: Sphere.h:450
Sphere::Normal
void Normal(const Vec3f &p, Vec3f *normal) const
Definition: Sphere.h:266
Sphere::Radius
void Radius(float radius)
Definition: Sphere.h:60
Sphere::Init
bool Init(const MiscLib::Vector< Vec3f > &samples)
Definition: Sphere.cpp:172
SphereAsSquaresParametrization::SphereAsSquaresParametrization
SphereAsSquaresParametrization()
Definition: Sphere.h:354
PointCloud
Definition: PointCloud.h:85
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
Sphere::DistanceAndNormal
float DistanceAndNormal(const Vec3f &p, Vec3f *normal) const
Definition: Sphere.h:273
Vec3f::dot
float dot(const Vec3f &v) const
Definition: basic.h:104
basic.h
std
Definition: Application.h:66
armarx::view_selection::skills::direction::state::center
state::Type center(state::Type previous)
Definition: LookDirection.cpp:233
UpperSphereAsSquaresParametrization::InSpace
bool InSpace(float u, float v, Vec3f *p) const
Definition: Sphere.h:407
LevMarLSWeight.h
PointCloud.h
DLL_LINKAGE
#define DLL_LINKAGE
Definition: basic.h:12
Sphere
Definition: Sphere.h:27
Sphere::LeastSquaresFit
bool LeastSquaresFit(const PointCloud &pc, MiscLib::Vector< size_t >::const_iterator begin, MiscLib::Vector< size_t >::const_iterator end)
Definition: Sphere.cpp:399
pc
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics Blackwell June If you use this software you should cite the aforementioned paper in any resulting publication Please send comments or bug reports to Ruwen Roland BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE Example usage This section shows how to use the library to detect the shapes in a point cloud PointCloud pc
Definition: ReadMe.txt:68
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
LevMar
bool LevMar(IteratorT begin, IteratorT end, FuncT &func, typename FuncT::ScalarType *param)
Definition: LevMarFitting.h:152
Sphere::Transform
void Transform(float scale, const Vec3f &translate)
Definition: Sphere.cpp:469
Sphere::SignedDistance
float SignedDistance(const Vec3f &p) const
Definition: Sphere.h:285