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 ];
 
 
  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)
 
static const Dimension dimension
 
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