GteApprOrthogonalPlane3.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>
13 
14 // Least-squares fit of a plane to (x,y,z) data by using distance measurements
15 // orthogonal to the proposed plane. The return value is 'true' iff the fit
16 // is unique (always successful, 'true' when a minimum eigenvalue is unique).
17 // The mParameters value is (P,N) = (origin,normal). The error for
18 // S = (x0,y0,z0) is (S-P)^T*(I - N*N^T)*(S-P).
19 
20 namespace gte
21 {
22 
23 template <typename Real>
25  :
26  public ApprQuery<Real, ApprOrthogonalPlane3<Real>, Vector3<Real>>
27 {
28 public:
29  // Initialize the model parameters to zero.
31 
32  // Basic fitting algorithm.
33  bool Fit(int numPoints, Vector3<Real> const* points);
34  std::pair<Vector3<Real>, Vector3<Real>> const& GetParameters() const;
35 
36  // Functions called by ApprQuery::RANSAC. See GteApprQuery.h for a
37  // detailed description.
38  int GetMinimumRequired() const;
39  Real Error(Vector3<Real> const& observation) const;
40  bool Fit(std::vector<Vector3<Real>> const& observations,
41  std::vector<int> const& indices);
42 
43 private:
44  std::pair<Vector3<Real>, Vector3<Real>> mParameters;
45 };
46 
47 
48 template <typename Real>
50 {
53 }
54 
55 template <typename Real>
57  Vector3<Real> const* points)
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  mean /= (Real)numPoints;
68 
69  // Compute the covariance matrix of the points.
70  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
71  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
72  for (int i = 0; i < numPoints; ++i)
73  {
74  Vector3<Real> diff = points[i] - mean;
75  covar00 += diff[0] * diff[0];
76  covar01 += diff[0] * diff[1];
77  covar02 += diff[0] * diff[2];
78  covar11 += diff[1] * diff[1];
79  covar12 += diff[1] * diff[2];
80  covar22 += diff[2] * diff[2];
81  }
82 
83  // Solve the eigensystem.
85  std::array<Real, 3> eval;
86  std::array<std::array<Real, 3>, 3> evec;
87  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
88  eval, evec);
89 
90  // The plane normal is the eigenvector in the direction of smallest
91  // variance of the points.
92  mParameters.first = mean;
93  mParameters.second = evec[0];
94 
95  // The fitted plane is unique when the minimum eigenvalue has
96  // multiplicity 1.
97  return eval[0] < eval[1];
98  }
99 
101  mParameters.second = Vector3<Real>::Zero();
102  return false;
103 }
104 
105 template <typename Real>
106 std::pair<Vector3<Real>, Vector3<Real>> const&
108 {
109  return mParameters;
110 }
111 
112 template <typename Real>
114 {
115  return 3;
116 }
117 
118 template <typename Real>
120 const
121 {
122  Vector3<Real> diff = observation - mParameters.first;
123  Real sqrlen = Dot(diff, diff);
124  Real dot = Dot(diff, mParameters.second);
125  Real error = std::abs(sqrlen - dot*dot);
126  return error;
127 }
128 
129 template <typename Real>
131  std::vector<Vector3<Real>> const& observations,
132  std::vector<int> const& indices)
133 {
134  if (static_cast<int>(indices.size()) >= GetMinimumRequired())
135  {
136  // Compute the mean of the points.
138  for (auto index : indices)
139  {
140  mean += observations[index];
141  }
142  mean /= (Real)indices.size();
143 
144  // Compute the covariance matrix of the points.
145  Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
146  Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
147  for (auto index : indices)
148  {
149  Vector3<Real> diff = observations[index] - mean;
150  covar00 += diff[0] * diff[0];
151  covar01 += diff[0] * diff[1];
152  covar02 += diff[0] * diff[2];
153  covar11 += diff[1] * diff[1];
154  covar12 += diff[1] * diff[2];
155  covar22 += diff[2] * diff[2];
156  }
157 
158  // Solve the eigensystem.
160  std::array<Real, 3> eval;
161  std::array<std::array<Real, 3>, 3> evec;
162  es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
163  eval, evec);
164 
165  // The plane normal is the eigenvector in the direction of smallest
166  // variance of the points.
167  mParameters.first = mean;
168  mParameters.second = evec[0];
169 
170  // The fitted plane is unique when the minimum eigenvalue has
171  // multiplicity 1.
172  return eval[0] < eval[1];
173  }
174 
176  mParameters.second = Vector3<Real>::Zero();
177  return false;
178 }
179 
180 
181 }
std::pair< Vector3< Real >, Vector3< Real > > mParameters
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
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)
Real Error(Vector3< Real > const &observation) const
bool Fit(int numPoints, Vector3< Real > const *points)
GLuint index
Definition: glcorearb.h:781
std::pair< Vector3< Real >, Vector3< Real > > const & GetParameters() const


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