ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkQuadEdgeMeshDecimationQuadricElementHelper.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
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 * https://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 "itkMathSVD.h"
23#include "vnl/vnl_vector_fixed.h"
24#include "vnl/vnl_matrix.h"
25#include <algorithm>
26
27#include "itkTriangleHelper.h"
28
29namespace itk
30{
32template <typename TPoint>
34{
35public:
37 using PointType = TPoint;
38 using CoordType = typename PointType::CoordinateType;
39
40 static constexpr unsigned int PointDimension = PointType::PointDimension;
41 static constexpr unsigned int NumberOfCoefficients = PointDimension * (PointDimension + 1 / 2 + PointDimension + 1);
42
43 using VectorType = typename PointType::VectorType;
44 using VNLMatrixType = vnl_matrix<CoordType>;
45 using VNLVectorType = vnl_vector_fixed<CoordType, Self::PointDimension>;
46 using CoefficientVectorType = vnl_vector_fixed<CoordType, Self::NumberOfCoefficients>;
48
49 // *****************************************************************
58
69
71
72 [[nodiscard]] CoefficientVectorType
74 {
75 return this->m_Coefficients;
76 }
77
80 {
82 return m_A;
83 }
84
87 {
89 return m_B;
90 }
91
92 [[nodiscard]] unsigned int
93 GetRank() const
94 {
95 return m_Rank;
96 }
97
99 [[nodiscard]] inline CoordType
100 ComputeError(const PointType & iP) const
101 {
102 // ComputeAMatrixAndBVector();
103 const auto svd = itk::Math::SVD(m_A, /*canonicalizeSigns=*/false);
104 const CoordType wmax = svd.W[0];
105 // Fold the absolute and relative singular-value tolerances into one rcond.
106 const CoordType rcond =
108 const CoordType oError = inner_product(iP.GetVnlVector(), svd.Recompose(rcond) * iP.GetVnlVector());
109
110 return this->m_Coefficients.back() - oError;
111 /*
112 CoordType oError( 0. );
113
114 std::vector< CoordType > pt( PointDimension + 1, 1. );
115
116 unsigned int dim1( 0 ), dim2, k( 0 );
117
118 while( dim1 < PointDimension )
119 {
120 pt[dim1] = iP[dim1];
121 ++dim1;
122 }
123
124 for( dim1 = 0; dim1 < PointDimension + 1; ++dim1 )
125 {
126 oError += this->m_Coefficients[k++] * pt[dim1] * pt[dim1];
127
128 for( dim2 = dim1 + 1; dim2 < PointDimension + 1; ++dim2 )
129 {
130 oError += 2. * this->m_Coefficients[k++] * pt[dim1] * pt[dim2];
131 }
132 }
133 oError += this->m_Coefficients[k++];
134
135 return oError;*/
136 }
137
139 inline CoordType
141 {
142 PointType optimal_location = ComputeOptimalLocation(iP);
143
144 return ComputeError(optimal_location);
145 }
146
149 {
151
152 const auto svd = itk::Math::SVD(m_A, /*canonicalizeSigns=*/false);
153 const CoordType wmax = svd.W[0];
154 const CoordType rcond =
156
157 m_Rank = svd.Rank(rcond);
158
159 const auto y = (m_B.as_vector() - m_A * iP.GetVnlVector());
160
161 VNLVectorType displacement = svd.Solve(y, rcond);
162
163 PointType oP;
164 for (unsigned int dim = 0; dim < PointDimension; ++dim)
165 {
166 oP[dim] = iP[dim] + displacement[dim];
167 }
168 return oP;
169 }
170
173 ComputeOptimalLocation(const unsigned int)
174 {}
175
176 void
178 const PointType & iP2,
179 const PointType & iP3,
180 const CoordType & iWeight = static_cast<CoordType>(1.))
181 {
182 const VectorType N = TriangleType::ComputeNormal(iP1, iP2, iP3);
183
184 AddPoint(iP1, N, iWeight);
185 }
186
187 void
188 AddPoint(const PointType & iP, const VectorType & iN, const CoordType & iWeight = static_cast<CoordType>(1.))
189 {
190 unsigned int k(0);
191 const CoordType d = -iN * iP.GetVectorFromOrigin();
192 for (unsigned int dim1 = 0; dim1 < PointDimension; ++dim1)
193 {
194 for (unsigned int dim2 = dim1; dim2 < PointDimension; ++dim2)
195 {
196 this->m_Coefficients[k++] += iWeight * iN[dim1] * iN[dim2];
197 }
198 this->m_Coefficients[k++] += iWeight * iN[dim1] * d;
199 }
200
201 this->m_Coefficients[k++] += iWeight * d * d;
202 }
203
204 // ***********************************************************************
205 // operators
206 Self &
207 operator=(const Self & iRight)
208 {
209 if (this != &iRight)
210 {
211 this->m_Coefficients = iRight.m_Coefficients;
212 }
213 return *this;
214 }
215
216 Self
217 operator+(const Self & iRight) const
218 {
219 return Self(this->m_Coefficients + iRight.m_Coefficients);
220 }
221
222 Self &
223 operator+=(const Self & iRight)
224 {
225 this->m_Coefficients += iRight.m_Coefficients;
226 return *this;
227 }
228
229 Self
230 operator-(const Self & iRight) const
231 {
232 return Self(this->m_Coefficients - iRight.m_Coefficients);
233 }
234
235 Self &
236 operator-=(const Self & iRight)
237 {
238 this->m_Coefficients -= iRight.m_Coefficients;
239 return *this;
240 }
241
242 Self
243 operator*(const CoordType & iV) const
244 {
245 Self oElement(this->m_Coefficients * iV);
246
247 return oElement;
248 }
249
250 Self &
252 {
253 this->m_Coefficients *= iV;
254 return *this;
255 }
256
257protected:
261 unsigned int m_Rank;
264 // bool m_MatrixFilled;
265
266 void
268 {
269 unsigned int k(0);
270 for (unsigned int dim1 = 0; dim1 < PointDimension; ++dim1)
271 {
272 for (unsigned int dim2 = dim1; dim2 < PointDimension; ++dim2)
273 {
274 m_A[dim1][dim2] = m_A[dim2][dim1] = m_Coefficients[k++];
275 }
276 m_B[dim1] = -m_Coefficients[k++];
277 }
278 // m_MatrixFilled = true;
279 }
280};
281} // namespace itk
282#endif
vnl_vector_fixed< CoordType, Self::PointDimension > VNLVectorType
PointType ComputeOptimalLocation(const unsigned int)
TODO to be implemented!!!
CoordType ComputeErrorAtOptimalLocation(const PointType &iP)
TODO this method should be really optimized!!!
CoordType ComputeError(const PointType &iP) const
TODO this method should be really optimized!!!
vnl_vector_fixed< CoordType, Self::NumberOfCoefficients > CoefficientVectorType
QuadEdgeMeshDecimationQuadricElementHelper(const CoefficientVectorType &iCoefficients)
void AddPoint(const PointType &iP, const VectorType &iN, const CoordType &iWeight=static_cast< CoordType >(1.))
void AddTriangle(const PointType &iP1, const PointType &iP2, const PointType &iP3, const CoordType &iWeight=static_cast< CoordType >(1.))
A convenience class for computation of various triangle elements in 2D or 3D.
static VectorType ComputeNormal(const PointType &iA, const PointType &iB, const PointType &iC)
FixedSquareSVDResult< TReal, VDim > SVD(const vnl_matrix_fixed< TReal, VDim, VDim > &A, bool canonicalizeSigns=true)
Singular value decomposition A = U diag(W) V^T, backed by Eigen.
Definition itkMathSVD.h:350
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....