GteApprSphere3.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
11 
12 // Least-squares fit of a sphere to a set of points. A successful fit is
13 // indicated by the return value of 'true'. The return value is the number
14 // of iterations used. If the number is the maximum, you can either accept
15 // the result or try increasing the maximum number and calling the function
16 // again. TODO: Currently, the test for terminating the algorithm is exact
17 // (diff == (0,0,0)). Expose an epsilon for this?
18 //
19 // If initialCenterIsAverage is set to 'true', the initial guess for the
20 // sphere center is the average of the data points. If the data points are
21 // clustered along a solid angle, ApprSphere32 is very slow to converge. If
22 // initialCenterIsAverage is set to 'false', the initial guess for the
23 // sphere center is computed using a least-squares estimate of the
24 // coefficients for a quadratic equation that represents a sphere. This
25 // approach tends to converge rapidly.
26 
27 namespace gte
28 {
29 
30 template <typename Real>
32 {
33 public:
34  unsigned int operator()(int numPoints, Vector3<Real> const* points,
35  unsigned int maxIterations, bool initialCenterIsAverage,
36  Sphere3<Real>& sphere);
37 };
38 
39 
40 template <typename Real>
41 unsigned int ApprSphere3<Real>::operator()(int numPoints,
42  Vector3<Real> const* points, unsigned int maxIterations,
43  bool initialCenterIsAverage, Sphere3<Real>& sphere)
44 {
45  // Compute the average of the data points.
46  Vector3<Real> average = points[0];
47  for (int i = 1; i < numPoints; ++i)
48  {
49  average += points[i];
50  }
51  Real invNumPoints = ((Real)1) / static_cast<Real>(numPoints);
52  average *= invNumPoints;
53 
54  // The initial guess for the center.
55  if (initialCenterIsAverage)
56  {
57  sphere.center = average;
58  }
59  else
60  {
61  ApprQuadraticSphere3<Real>()(numPoints, points, sphere);
62  }
63 
64  unsigned int iteration;
65  for (iteration = 0; iteration < maxIterations; ++iteration)
66  {
67  // Update the iterates.
68  Vector3<Real> current = sphere.center;
69 
70  // Compute average L, dL/da, dL/db, dL/dc.
71  Real lenAverage = (Real)0;
72  Vector3<Real> derLenAverage = Vector3<Real>::Zero();
73  for (int i = 0; i < numPoints; ++i)
74  {
75  Vector3<Real> diff = points[i] - sphere.center;
76  Real length = Length(diff);
77  if (length >(Real)0)
78  {
79  lenAverage += length;
80  Real invLength = ((Real)1) / length;
81  derLenAverage -= invLength * diff;
82  }
83  }
84  lenAverage *= invNumPoints;
85  derLenAverage *= invNumPoints;
86 
87  sphere.center = average + lenAverage * derLenAverage;
88  sphere.radius = lenAverage;
89 
90  Vector3<Real> diff = sphere.center - current;
91  if (diff == Vector3<Real>::Zero())
92  {
93  break;
94  }
95  }
96 
97  return ++iteration;
98 }
99 
100 
101 }
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
static Vector Zero()
Definition: GteVector.h:295
unsigned int operator()(int numPoints, Vector3< Real > const *points, unsigned int maxIterations, bool initialCenterIsAverage, Sphere3< Real > &sphere)
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:790
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
Vector< N, Real > center


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59