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 ) );
308 bool unit_u =
false )
310 ASSERT( pts.size() == u.size() );
311 if ( pts.size() < 3 )
return 0.0;
312 if ( pts.size() == 3 )
314 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
318 for (
Index i = 0; i < pts.size(); i++ )
320 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
343 (void)a; (void)b; (void)c; (void)u;
366 for (
const auto& u : vu ) avg_u += u;
367 const Scalar l = avg_u.norm();
370 trace.
warning() <<
"[CorrectedNormalCurrentFormula::mu2ConstantUAtVertex]"
371 <<
" Invalid surrounding normal vectors at vertex "
373 <<
" Unit normal vectors should lie strictly in the same"
374 <<
" hemisphere." << std::endl;
379 const auto n = vu.size();
380 for (
size_t i = 0; i < n; ++i )
382 ST st( avg_u, vu[ i ], vu[ (i+1) % n ] );
383 mu2 += st.algebraicArea();
406 bool unit_u =
false )
422 return 0.5 * ( ua.crossProduct( ub ).dot( uc ) );
433 (void) pts; (void) u;
447 bool unit_u =
false )
449 ASSERT( pts.size() == u.size() );
450 if ( pts.size() < 3 )
return 0.0;
451 if ( pts.size() == 3 )
453 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
457 for (
Index i = 0; i < pts.size(); i++ )
459 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
482 (void)a; (void)b; (void)c; (void)u;
483 return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
506 RealTensor M { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
509 const Scalar l1 = std::min( e1.norm(), 1.0 );
510 if ( l1 < 1e-10 )
return M;
512 const Scalar psi = asin( l1 );
513 const Scalar sin_psi = sin( psi );
514 const Scalar sin_2psi = sin( 2.0 * psi );
516 const RealVector e1_x_ur = e1.crossProduct( ur );
521 Scalar v = (-psi - 0.5*sin_2psi) * e_x_ur[ i ] * e1_x_ur[ j ]
522 + (sin_psi*sin_psi) * ( e_x_ur[ i ] * ur[ j ]
523 - e_x_e1_x_ur[ i ] * e1_x_ur[ j ] )
524 + (psi - 0.5*sin_2psi) * e_x_e1_x_ur[ i ] * ur[ j ];
525 M.setComponent( i, j, -0.5 * v );
546 bool unit_u =
false )
552 if ( unit_u ) uM /= uM.norm();
563 0.5 * uM.dot( uac[ j ] * X.crossProduct( ab )
564 - uab[ j ] * X.crossProduct( ac ) );
580 return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
593 bool unit_u =
false )
595 ASSERT( pts.size() == u.size() );
596 if ( pts.size() < 3 )
return RealTensor { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
597 if ( pts.size() == 3 )
599 u[ 0 ], u[ 1 ], u[ 2 ], unit_u );
602 RealTensor T = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
603 for (
Index i = 0; i < pts.size(); i++ )
605 ub, u[ i ], u[ (i+1)%pts.size() ], unit_u );
624 for (
auto p : pts ) b += p;
636 for (
auto v : vecs ) avg += v;
637 auto avg_norm = avg.norm();
638 return avg_norm != 0.0 ? avg / avg_norm : avg;
657#undef CorrectedNormalCurrentFormula_RECURSES
static Self base(Dimension k, Component val=1)
TEuclideanRing Component
Type for Vector elements.
static const Dimension dimension
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