ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkQuadEdgeMeshDecimationQuadricElementHelper.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkQuadEdgeMeshDecimationQuadricElementHelper_h
19 #define itkQuadEdgeMeshDecimationQuadricElementHelper_h
20 
21 #include "itkPoint.h"
22 #include "vnl/vnl_vector_fixed.h"
23 #include "vnl/vnl_matrix.h"
24 #include "vnl/algo/vnl_matrix_inverse.h"
25 
26 #include "itkTriangleHelper.h"
27 
28 namespace itk
29 {
31 template< typename TPoint >
33 {
34 public:
35 
37  using PointType = TPoint;
38  using CoordType = typename PointType::CoordRepType;
39 
40  static constexpr unsigned int PointDimension = PointType::PointDimension;
41  static constexpr unsigned int NumberOfCoefficients = PointDimension * ( PointDimension + 1 / 2 + PointDimension + 1);
42 
44  using VNLMatrixType = vnl_matrix< CoordType >;
45  using VNLVectorType = vnl_vector_fixed< CoordType,
47  using CoefficientVectorType = vnl_vector_fixed< CoordType,
50 
51  // *****************************************************************
53  m_Coefficients(itk::NumericTraits< CoordType >::ZeroValue()),
55  m_B(itk::NumericTraits< CoordType >::ZeroValue()),
56  m_SVDAbsoluteThreshold( static_cast< CoordType >( 1e-6 ) ),
57  m_SVDRelativeThreshold( static_cast< CoordType >( 1e-3 ) )
58  {
59  this->m_Rank = PointDimension;
60  }
61 
63  m_Coefficients(iCoefficients),
65  m_B(itk::NumericTraits< CoordType >::ZeroValue()),
66  m_SVDAbsoluteThreshold( static_cast< CoordType >( 1e-3 ) ),
67  m_SVDRelativeThreshold( static_cast< CoordType >( 1e-3 ) )
68  {
69  this->m_Rank = PointDimension;
71  }
72 
74 
76  {
77  return this->m_Coefficients;
78  }
79 
81  {
83  return m_A;
84  }
85 
87  {
89  return m_B;
90  }
91 
92  unsigned int GetRank() const
93  {
94  return m_Rank;
95  }
96 
98  inline CoordType ComputeError(const PointType & iP) const
99  {
100  // ComputeAMatrixAndBVector();
101  vnl_svd< CoordType > svd(m_A, m_SVDAbsoluteThreshold);
102  svd.zero_out_relative(m_SVDRelativeThreshold);
103  CoordType oError = inner_product( iP.GetVnlVector(), svd.recompose() * iP.GetVnlVector() );
104 
105  return this->m_Coefficients[this->m_Coefficients.size() - 1] - oError;
106  /*
107  CoordType oError( 0. );
108 
109  std::vector< CoordType > pt( PointDimension + 1, 1. );
110 
111  unsigned int dim1( 0 ), dim2, k( 0 );
112 
113  while( dim1 < PointDimension )
114  {
115  pt[dim1] = iP[dim1];
116  ++dim1;
117  }
118 
119  for( dim1 = 0; dim1 < PointDimension + 1; ++dim1 )
120  {
121  oError += this->m_Coefficients[k++] * pt[dim1] * pt[dim1];
122 
123  for( dim2 = dim1 + 1; dim2 < PointDimension + 1; ++dim2 )
124  {
125  oError += 2. * this->m_Coefficients[k++] * pt[dim1] * pt[dim2];
126  }
127  }
128  oError += this->m_Coefficients[k++];
129 
130  return oError;*/
131  }
132 
135  {
136  PointType optimal_location = ComputeOptimalLocation(iP);
137 
138  return ComputeError(optimal_location);
139  }
140 
142  {
144 
145  vnl_svd< CoordType > svd(m_A, m_SVDAbsoluteThreshold);
146  svd.zero_out_relative(m_SVDRelativeThreshold);
147 
148  m_Rank = svd.rank();
149 
150  VNLVectorType y = m_B.as_vector() - m_A *iP.GetVnlVector();
151 
152  VNLVectorType displacement = svd.solve(y);
153  PointType oP;
154 
155  for ( unsigned int dim = 0; dim < PointDimension; dim++ )
156  {
157  oP[dim] = iP[dim] + displacement[dim];
158  }
159 
160  return oP;
161  }
162 
165  const unsigned int & )
166  {}
167 
168  void AddTriangle( const PointType & iP1,
169  const PointType & iP2,
170  const PointType & iP3,
171  const CoordType & iWeight = static_cast< CoordType >( 1. ) )
172  {
173  VectorType N = TriangleType::ComputeNormal(iP1, iP2, iP3);
174 
175  AddPoint(iP1, N, iWeight);
176  }
177 
178  void AddPoint( const PointType & iP,
179  const VectorType & iN,
180  const CoordType & iWeight = static_cast< CoordType >( 1. ) )
181  {
182  unsigned int k(0), dim1, dim2;
183 
184  CoordType d = -iN *iP.GetVectorFromOrigin();
185 
186  for ( dim1 = 0; dim1 < PointDimension; ++dim1 )
187  {
188  for ( dim2 = dim1; dim2 < PointDimension; ++dim2 )
189  {
190  this->m_Coefficients[k++] += iWeight * iN[dim1] * iN[dim2];
191  }
192  this->m_Coefficients[k++] += iWeight * iN[dim1] * d;
193  }
194 
195  this->m_Coefficients[k++] += iWeight * d * d;
196  }
197 
198  // ***********************************************************************
199  // operators
200  Self & operator=(const Self & iRight)
201  {
202  if(this != &iRight)
203  {
204  this->m_Coefficients = iRight.m_Coefficients;
205  }
206  return *this;
207  }
208 
209  Self operator+(const Self & iRight) const
210  {
211  return Self(this->m_Coefficients + iRight.m_Coefficients);
212  }
213 
214  Self & operator+=(const Self & iRight)
215  {
216  this->m_Coefficients += iRight.m_Coefficients;
217  return *this;
218  }
219 
220  Self operator-(const Self & iRight) const
221  {
222  return Self(this->m_Coefficients - iRight.m_Coefficients);
223  }
224 
225  Self & operator-=(const Self & iRight)
226  {
227  this->m_Coefficients -= iRight.m_Coefficients;
228  return *this;
229  }
230 
231  Self operator*(const CoordType & iV) const
232  {
233  Self oElement = Self(this->m_Coefficients * iV);
234 
235  return oElement;
236  }
237 
238  Self & operator*=(const CoordType & iV)
239  {
240  this->m_Coefficients *= iV;
241  return *this;
242  }
243 
244 protected:
245 
249  unsigned int m_Rank;
252  //bool m_MatrixFilled;
253 
255  {
256  unsigned int k(0), dim1, dim2;
257 
258  for ( dim1 = 0; dim1 < PointDimension; ++dim1 )
259  {
260  for ( dim2 = dim1; dim2 < PointDimension; ++dim2 )
261  {
262  m_A[dim1][dim2] = m_A[dim2][dim1] = m_Coefficients[k++];
263  }
264  m_B[dim1] = -m_Coefficients[k++];
265  }
266  //m_MatrixFilled = true;
267  }
268 };
269 }
270 #endif
vnl_vector_fixed< CoordType, Self::NumberOfCoefficients > CoefficientVectorType
Define numeric traits for std::vector.
QuadEdgeMeshDecimationQuadricElementHelper(const CoefficientVectorType &iCoefficients)
static VectorType ComputeNormal(const PointType &iA, const PointType &iB, const PointType &iC)
Compute Normal vector to the triangle formed by (iA,iB,iC)
void AddPoint(const PointType &iP, const VectorType &iN, const CoordType &iWeight=static_cast< CoordType >(1.))
A convenience class for computation of various triangle elements in 2D or 3D.
CoordType ComputeError(const PointType &iP) const
TODO this method should be really optimized!!!
CoordType ComputeErrorAtOptimalLocation(const PointType &iP)
TODO this method should be really optimized!!!
vnl_vector_fixed< CoordType, Self::PointDimension > VNLVectorType
static constexpr double e
The base of the natural logarithm or Euler&#39;s number
Definition: itkMath.h:53
PointType ComputeOptimalLocation(const unsigned int &)
TODO to be implemented!!!
void AddTriangle(const PointType &iP1, const PointType &iP2, const PointType &iP3, const CoordType &iWeight=static_cast< CoordType >(1.))