GteApprEllipse2.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 // The ellipse in general form is X^t A X + B^t X + C = 0 where A is a
11 // positive definite 2x2 matrix, B is a 2x1 vector, C is a scalar, and X is
12 // a 2x1 vector X. Completing the square, (X-U)^t A (X-U) = U^t A U - C
13 // where U = -0.5 A^{-1} B. Define M = A/(U^t A U - C). The ellipse is
14 // (X-U)^t M (X-U) = 1. Factor M = R^t D R where R is orthonormal and D is
15 // diagonal with positive diagonal terms. The ellipse in factored form is
16 // (X-U)^t R^t D^t R (X-U) = 1.
17 //
18 // Find the least squares fit of a set of N points P[0] through P[N-1].
19 // The return value is the least-squares energy function at (U,R,D).
20 
26 
27 namespace gte
28 {
29 
30 template <typename Real>
32 {
33 public:
34  Real operator()(int numPoints, Vector2<Real> const* points,
35  Vector2<Real>& center, Matrix2x2<Real>& rotate, Real diagonal[2]);
36 
37 private:
38  static Real Energy(int numPoints, Vector2<Real> const* points,
39  Real const* input);
40 };
41 
42 
43 template <typename Real>
44 Real ApprEllipse2<Real>::operator()(int numPoints,
45  Vector2<Real> const* points, Vector2<Real>& center,
46  Matrix2x2<Real>& rotate, Real diagonal[2])
47 {
48  // Energy function is E : R^5 -> R where
49  // V = (V0, V1, V2, V3, V4)
50  // = (D[0], D[1], U.x, U.y, atan2(R(0,1),R(0,0))).
51  std::function<Real(Real const*)> energy =
52  [numPoints, points](Real const* input)
53  {
54  return Energy(numPoints, points, input);
55  };
56 
57  MinimizeN<Real> minimizer(5, energy, 8, 8, 32);
58 
59  // The initial guess for the minimizer is based on an oriented box that
60  // contains the points.
62  GetContainer(numPoints, points, box);
63  center = box.center;
64  for (int i = 0; i < 2; ++i)
65  {
66  rotate.SetRow(i, box.axis[i]);
67  diagonal[i] = box.extent[i];
68  }
69 
70  Real angle = atan2(rotate(0, 1), rotate(0, 0));
71  Real e0 =
72  diagonal[0] * std::abs(rotate(0, 0)) +
73  diagonal[1] * std::abs(rotate(1, 0));
74  Real e1 =
75  diagonal[0] * std::abs(rotate(0, 1)) +
76  diagonal[1] * std::abs(rotate(1, 1));
77 
78  Real v0[5] =
79  {
80  ((Real)0.5)*diagonal[0],
81  ((Real)0.5)*diagonal[1],
82  center[0] - e0,
83  center[1] - e1,
84  -(Real)GTE_C_PI
85  };
86 
87  Real v1[5] =
88  {
89  ((Real)2)*diagonal[0],
90  ((Real)2)*diagonal[1],
91  center[0] + e0,
92  center[1] + e1,
93  (Real)GTE_C_PI
94  };
95 
96  Real vInitial[5] =
97  {
98  diagonal[0],
99  diagonal[1],
100  center[0],
101  center[1],
102  angle
103  };
104 
105  Real vMin[5], error;
106  minimizer.GetMinimum(v0, v1, vInitial, vMin, error);
107 
108  diagonal[0] = vMin[0];
109  diagonal[1] = vMin[1];
110  center[0] = vMin[2];
111  center[1] = vMin[3];
112  MakeRotation(-vMin[4], rotate);
113 
114  return error;
115 }
116 
117 template <typename Real>
119  Real const* input)
120 {
121  // Build rotation matrix.
122  Matrix2x2<Real> rotate;
123  MakeRotation(-input[4], rotate);
124 
126  Vector2<Real>::Unit(1) }, { input[0], input[1] });
127 
128  // Transform the points to the coordinate system of center C and
129  // columns of rotation R.
131  Real energy = (Real)0;
132  for (int i = 0; i < numPoints; ++i)
133  {
134  Vector2<Real> diff = points[i] - Vector2<Real>{ input[2], input[3] };
135  Vector2<Real> prod = rotate * diff;
136  Real dist = peQuery(prod, ellipse).distance;
137  energy += dist;
138  }
139 
140  return energy;
141 }
142 
143 
144 }
std::array< Vector< N, Real >, N > axis
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
bool GetContainer(int numPoints, Vector3< Real > const *points, Capsule3< Real > &capsule)
GLfloat GLfloat v1
Definition: glcorearb.h:812
GLfloat angle
Definition: glext.h:6466
Real operator()(int numPoints, Vector2< Real > const *points, Vector2< Real > &center, Matrix2x2< Real > &rotate, Real diagonal[2])
static Real Energy(int numPoints, Vector2< Real > const *points, Real const *input)
Vector< N, Real > extent
void GetMinimum(Real const *t0, Real const *t1, Real const *tInitial, Real *tMin, Real &fMin)
Definition: GteMinimizeN.h:93
GLfixed GLfixed GLint GLint GLfixed points
Definition: glext.h:4927
#define GTE_C_PI
Definition: GteConstants.h:17
GLfloat v0
Definition: glcorearb.h:811
void MakeRotation(Real angle, Matrix2x2< Real > &rotation)
Definition: GteMatrix2x2.h:51
GLenum GLenum GLenum input
Definition: glext.h:9913
void SetRow(int r, Vector< NumCols, Real > const &vec)
Definition: GteMatrix.h:352
Vector< N, Real > center
static Vector Unit(int d)


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