GteApprOrthogonalLine2.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/GteVector2.h>
12 #include <Mathematics/GteLine.h>
14 
15 // Least-squares fit of a line to (x,y) 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) 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, ApprOrthogonalLine2<Real>, Vector2<Real>>
28 {
29 public:
30  // Initialize the model parameters to zero.
32 
33  // Basic fitting algorithm.
34  bool Fit(int numPoints, Vector2<Real> const* points);
35  Line2<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(Vector2<Real> const& observation) const;
41  bool Fit(std::vector<Vector2<Real>> const& observations,
42  std::vector<int> const& indices);
43 
44 private:
46 };
47 
48 
49 template <typename Real>
51  :
52  mParameters(Vector2<Real>::Zero(), Vector2<Real>::Zero())
53 {
54 }
55 
56 template <typename Real>
57 bool ApprOrthogonalLine2<Real>::Fit(int numPoints,
58  Vector2<Real> const* points)
59 {
60  if (numPoints >= GetMinimumRequired() && points)
61  {
62  // Compute the mean of the points.
64  for (int i = 0; i < numPoints; ++i)
65  {
66  mean += points[i];
67  }
68  mean /= (Real)numPoints;
69 
70  // Compute the covariance matrix of the points.
71  Real covar00 = (Real)0, covar01 = (Real)0, covar11 = (Real)0;
72  for (int i = 0; i < numPoints; ++i)
73  {
74  Vector2<Real> diff = points[i] - mean;
75  covar00 += diff[0] * diff[0];
76  covar01 += diff[0] * diff[1];
77  covar11 += diff[1] * diff[1];
78  }
79 
80  // Solve the eigensystem.
82  std::array<Real, 2> eval;
83  std::array<std::array<Real, 2>, 2> evec;
84  es(covar00, covar01, covar11, +1, eval, evec);
85 
86  // The line direction is the eigenvector in the direction of largest
87  // variance of the points.
88  mParameters.origin = mean;
89  mParameters.direction = evec[1];
90 
91  // The fitted line is unique when the maximum eigenvalue has
92  // multiplicity 1.
93  return eval[0] < eval[1];
94  }
95 
97  return false;
98 }
99 
100 template <typename Real>
102 {
103  return mParameters;
104 }
105 
106 template <typename Real>
108 {
109  return 2;
110 }
111 
112 template <typename Real>
113 Real ApprOrthogonalLine2<Real>::Error(Vector2<Real> const& observation) const
114 {
115  Vector2<Real> diff = observation - mParameters.origin;
116  Real sqrlen = Dot(diff, diff);
117  Real dot = Dot(diff, mParameters.direction);
118  Real error = std::abs(sqrlen - dot*dot);
119  return error;
120 }
121 
122 template <typename Real>
124  std::vector<Vector2<Real>> const& observations,
125  std::vector<int> const& indices)
126 {
127  if (static_cast<int>(indices.size()) >= GetMinimumRequired())
128  {
129  // Compute the mean of the points.
131  for (auto index : indices)
132  {
133  mean += observations[index];
134  }
135  mean /= (Real)indices.size();
136 
137  // Compute the covariance matrix of the points.
138  Real covar00 = (Real)0, covar01 = (Real)0, covar11 = (Real)0;
139  for (auto index : indices)
140  {
141  Vector2<Real> diff = observations[index] - mean;
142  covar00 += diff[0] * diff[0];
143  covar01 += diff[0] * diff[1];
144  covar11 += diff[1] * diff[1];
145  }
146 
147  // Solve the eigensystem.
148  // Solve the eigensystem.
150  std::array<Real, 2> eval;
151  std::array<std::array<Real, 2>, 2> evec;
152  es(covar00, covar01, covar11, +1, eval, evec);
153 
154  // The line direction is the eigenvector in the direction of largest
155  // variance of the points.
156  mParameters.origin = mean;
157  mParameters.direction = evec[1];
158 
159  // The fitted line is unique when the maximum eigenvalue has
160  // multiplicity 1.
161  return eval[0] < eval[1];
162  }
163 
165  return false;
166 }
167 
168 
169 }
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
Line2< Real > const & GetParameters() const
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
GLsizei GLenum const void * indices
Definition: glcorearb.h:401
static Vector Zero()
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real Error(Vector2< Real > const &observation) const
bool Fit(int numPoints, Vector2< Real > const *points)
GLuint index
Definition: glcorearb.h:781


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