31#if defined(CorrectedNormalCurrentFormula_RECURSES)
32#error Recursive header files inclusion detected in CorrectedNormalCurrentFormula.h
35#define CorrectedNormalCurrentFormula_RECURSES
37#if !defined CorrectedNormalCurrentFormula_h
39#define CorrectedNormalCurrentFormula_h
45#include "DGtal/base/Common.h"
46#include "DGtal/math/linalg/SimpleMatrix.h"
47#include "DGtal/geometry/tools/SphericalTriangle.h"
98 template <
typename TRealPo
int,
typename TRealVector >
146 bool unit_u =
false )
153 auto uM_norm = uM.norm();
154 uM = uM_norm == 0.0 ? uM : uM / uM_norm;
167 if ( pts.size() < 3 )
return 0.0;
168 if ( pts.size() == 3 )
172 for (
Index i = 0; i < pts.size(); i++ )
173 a +=
mu0ConstantU( b, pts[ i ], pts[ (i+1)%pts.size() ], u );
187 bool unit_u =
false )
189 ASSERT( pts.size() == u.size() );
190 if ( pts.size() < 3 )
return 0.0;
191 if ( pts.size() == 3 )
193 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
197 for (
Index i = 0; i < pts.size(); i++ )
199 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
232 const Scalar l1 = std::min( e1.norm(), 1.0 );
233 if ( l1 < 1e-10 )
return 0.0;
235 const Scalar Psi = asin( l1 );
236 return -Psi * e.dot( e1 );
252 (void)a; (void)b; (void)c; (void)u;
274 bool unit_u =
false )
278 if ( unit_u ) uM /= uM.norm();
279 return 0.5 * ( uM.crossProduct( uc - ub ).dot( a )
280 + uM.crossProduct( ua - uc ).dot( b )
281 + uM.crossProduct( ub - ua ).dot( c ) );
306 bool unit_u =
false )
308 ASSERT( pts.size() == u.size() );
309 if ( pts.size() < 3 )
return 0.0;
310 if ( pts.size() == 3 )
312 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
316 for (
Index i = 0; i < pts.size(); i++ )
318 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
341 (void)a; (void)b; (void)c; (void)u;
364 for (
const auto& u : vu ) avg_u += u;
365 const Scalar l = avg_u.norm();
368 trace.
warning() <<
"[CorrectedNormalCurrentFormula::mu2ConstantUAtVertex]"
369 <<
" Invalid surrounding normal vectors at vertex "
371 <<
" Unit normal vectors should lie strictly in the same"
372 <<
" hemisphere." << std::endl;
377 const auto n = vu.size();
378 for (
auto i = 0; i < n; ++i )
380 ST st( avg_u, vu[ i ], vu[ (i+1) % n ] );
381 mu2 += st.algebraicArea();
404 bool unit_u =
false )
416 return 0.5 * ( ua.crossProduct( ub ).dot( uc ) );
427 (void) pts; (void) u;
441 bool unit_u =
false )
443 ASSERT( pts.size() == u.size() );
444 if ( pts.size() < 3 )
return 0.0;
445 if ( pts.size() == 3 )
447 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
451 for (
Index i = 0; i < pts.size(); i++ )
453 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
476 (void)a; (void)b; (void)c; (void)u;
477 return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
500 RealTensor M { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
503 const Scalar l1 = std::min( e1.norm(), 1.0 );
504 if ( l1 < 1e-10 )
return M;
506 const Scalar psi = asin( l1 );
507 const Scalar sin_psi = sin( psi );
508 const Scalar sin_2psi = sin( 2.0 * psi );
510 const RealVector e1_x_ur = e1.crossProduct( ur );
515 Scalar v = (-psi - 0.5*sin_2psi) * e_x_ur[ i ] * e1_x_ur[ j ]
516 + (sin_psi*sin_psi) * ( e_x_ur[ i ] * ur[ j ]
517 - e_x_e1_x_ur[ i ] * e1_x_ur[ j ] )
518 + (psi - 0.5*sin_2psi) * e_x_e1_x_ur[ i ] * ur[ j ];
519 M.setComponent( i, j, -0.5 * v );
540 bool unit_u =
false )
546 if ( unit_u ) uM /= uM.norm();
557 0.5 * uM.dot( uac[ j ] * X.crossProduct( ab )
558 - uab[ j ] * X.crossProduct( ac ) );
574 return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
587 bool unit_u =
false )
589 ASSERT( pts.size() == u.size() );
590 if ( pts.size() < 3 )
return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
591 if ( pts.size() == 3 )
593 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
596 RealTensor T = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
597 for (
Index i = 0; i < pts.size(); i++ )
599 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
618 for (
auto p : pts ) b += p;
630 for (
auto v : vecs ) avg += v;
631 auto avg_norm = avg.norm();
632 return avg_norm != 0.0 ? avg / avg_norm : avg;
651#undef CorrectedNormalCurrentFormula_RECURSES
static Self base(Dimension k, Component val=1)
TEuclideanRing Component
Type for Vector elements.
static const Dimension dimension
Copy of the static dimension of the Point/Vector.
Aim: implements basic MxN Matrix services (M,N>=1).
void setComponent(const DGtal::Dimension i, const DGtal::Dimension j, const Component &aValue)
Aim: Represent a triangle drawn onto a sphere of radius 1.
Scalar algebraicArea() const
DGtal is the top-level namespace which contains all DGtal functions and types.
auto crossProduct(PointVector< 3, LeftEuclideanRing, LeftContainer > const &lhs, PointVector< 3, RightEuclideanRing, RightContainer > const &rhs) -> decltype(DGtal::constructFromArithmeticConversion(lhs, rhs))
Cross product of two 3D Points/Vectors.
DGtal::uint32_t Dimension