GteApprOrthogonalLine3.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 
10 #include <Mathematics/GteVector3.h>
12 #include <Mathematics/GteLine.h>
14 
15 // Least-squares fit of a line to (x,y,z) data by using distance measurements
16 // orthogonal to the proposed line. The return value is 'true' iff the fit
17 // is unique (always successful, 'true' when a minimum eigenvalue is unique).
18 // The mParameters value is a line with (P,D) = (origin,direction). The
19 // error for S = (x0,y0,z0) is (S-P)^T*(I - D*D^T)*(S-P).
20 
21 namespace gte
22 {
23 
24 template <typename Real>
26  :
27  public ApprQuery<Real, ApprOrthogonalLine3<Real>, Vector3<Real>>
28 {
29 public:
30  // Initialize the model parameters to zero.
32 
33  // Basic fitting algorithm.
34  bool Fit(int numPoints, Vector3<Real> const* points);
35  Line3<Real> const& GetParameters() const;
36 
37  // Functions called by ApprQuery::RANSAC. See GteApprQuery.h for a
38  // detailed description.
39  int GetMinimumRequired() const;
40  Real Error(Vector3<Real> const& observation) const;
41  bool Fit(std::vector<Vector3<Real>> const& observations,
42  std::vector<int> const& indices);
43 
44 private:
46 };
47 
48 
49 template <typename Real>
51  :
52  mParameters(Vector3<Real>::Zero(), Vector3<Real>::Zero())
53 {
54 }
55 
56 template <typename Real>
58 {
59  if (numPoints >= GetMinimumRequired() && points)
60  {
61  // Compute the mean of the points.
63  for (int i = 0; i < numPoints; ++i)
64  {
65  mean += points[i];
66  }
67  Real invSize = ((Real)1) / (Real)numPoints;
68  mean *= invSize;
69 
70  // Compute the covariance matrix of the points.
71  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
72  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
73  for (int i = 0; i < numPoints; ++i)
74  {
75  Vector3<Real> diff = points[i] - mean;
76  covar00 += diff[0] * diff[0];
77  covar01 += diff[0] * diff[1];
78  covar02 += diff[0] * diff[2];
79  covar11 += diff[1] * diff[1];
80  covar12 += diff[1] * diff[2];
81  covar22 += diff[2] * diff[2];
82  }
83  covar00 *= invSize;
84  covar01 *= invSize;
85  covar02 *= invSize;
86  covar11 *= invSize;
87  covar12 *= invSize;
88  covar22 *= invSize;
89 
90  // Solve the eigensystem.
92  std::array<Real, 3> eval;
93  std::array<std::array<Real, 3>, 3> evec;
94  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
95  eval, evec);
96 
97  // The line direction is the eigenvector in the direction of largest
98  // variance of the points.
99  mParameters.origin = mean;
100  mParameters.direction = evec[2];
101 
102  // The fitted line is unique when the maximum eigenvalue has
103  // multiplicity 1.
104  return eval[1]< eval[2];
105  }
106 
108  return false;
109 }
110 
111 template <typename Real>
113 {
114  return mParameters;
115 }
116 
117 template <typename Real>
119 {
120  return 2;
121 }
122 
123 template <typename Real>
124 Real ApprOrthogonalLine3<Real>::Error(Vector3<Real> const& observation) const
125 {
126  Vector3<Real> diff = observation - mParameters.origin;
127  Real sqrlen = Dot(diff, diff);
128  Real dot = Dot(diff, mParameters.direction);
129  Real error = std::abs(sqrlen - dot*dot);
130  return error;
131 }
132 
133 template <typename Real>
135  std::vector<Vector3<Real>> const& observations,
136  std::vector<int> const& indices)
137 {
138  if (static_cast<int>(indices.size()) >= GetMinimumRequired())
139  {
140  // Compute the mean of the points.
142  for (auto index : indices)
143  {
144  mean += observations[index];
145  }
146  Real invSize = ((Real)1) / (Real)indices.size();
147  mean *= invSize;
148 
149  // Compute the covariance matrix of the points.
150  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
151  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
152  for (auto index : indices)
153  {
154  Vector3<Real> diff = observations[index] - mean;
155  covar00 += diff[0] * diff[0];
156  covar01 += diff[0] * diff[1];
157  covar02 += diff[0] * diff[2];
158  covar11 += diff[1] * diff[1];
159  covar12 += diff[1] * diff[2];
160  covar22 += diff[2] * diff[2];
161  }
162  covar00 *= invSize;
163  covar01 *= invSize;
164  covar02 *= invSize;
165  covar11 *= invSize;
166  covar12 *= invSize;
167  covar22 *= invSize;
168 
169  // Solve the eigensystem.
171  std::array<Real, 3> eval;
172  std::array<std::array<Real, 3>, 3> evec;
173  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
174  eval, evec);
175 
176  // The line direction is the eigenvector in the direction of largest
177  // variance of the points.
178  mParameters.origin = mean;
179  mParameters.direction = evec[2];
180 
181  // The fitted line is unique when the maximum eigenvalue has
182  // multiplicity 1.
183  return eval[1]< eval[2];
184  }
185 
187  return false;
188 }
189 
190 
191 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
Real Error(Vector3< Real > const &observation) const
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
GLsizei GLenum const void * indices
Definition: glcorearb.h:401
static Vector Zero()
Definition: GteVector.h:295
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
bool Fit(int numPoints, Vector3< Real > const *points)
GLuint index
Definition: glcorearb.h:781
Line3< Real > const & GetParameters() const


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