35 #ifndef AIMS_MOMENT_MOMENT_H
36 #define AIMS_MOMENT_MOMENT_H
47 template<
class T >
class Moment;
98 double cx()
const {
return _cx; }
99 double cy()
const {
return _cy; }
113 const double&
m0()
const {
return _m0; }
116 const double *
m1()
const {
return &
_m1[ 0 ]; }
118 const double *
m2()
const {
return &
_m2[ 0 ]; }
120 const double *
m3()
const {
return &
_m3[ 0 ]; }
129 virtual void update(
double,
double,
double,
int );
163 template<
class T >
inline
165 _sum( 0.0 ), _m0( 0.0 )
170 template<
class T >
inline
172 : _cx( other.cx() ), _cy( other.cy() ), _cz( other.cz() ),
173 _ct( other.ct() ), _sum( other.
sum() ), _m0( other.m0() ),
174 _eigenValue( other.eigenValue() ),
175 _eigenVector( other.eigenVector() )
179 for ( i=0; i<3; i++ )
182 _m1[ i ] = other.
m1()[ i ];
184 for ( i=0; i<6; i++ )
_m2[ i ] = other.
m2()[ i ];
185 for ( i=0; i<9; i++ )
_m3[ i ] = other.
m3()[ i ];
189 template<
class T >
inline
221 #pragma GCC diagnostic push
222 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
223 template<
class T >
inline
226 update( (
double)pt[ 0 ], (
double)pt[ 1 ], (
double)pt[ 2 ], dir );
230 template<
class T >
inline
233 update( pt[ 0 ], pt[ 1 ], pt[ 2 ], dir );
237 template<
class T >
inline
242 #pragma GCC diagnostic pop
245 template<
class T >
inline
249 carto::AllocatorContext::fast() );
251 _eigenVector( 0, 0 ) = _m2[ 0 ];
252 _eigenVector( 1, 1 ) = _m2[ 1 ];
253 _eigenVector( 2, 2 ) = _m2[ 2 ];
254 _eigenVector( 0, 1 ) = _eigenVector( 1, 0 ) = _m2[ 3 ];
255 _eigenVector( 0, 2 ) = _eigenVector( 2, 0 ) = _m2[ 4 ];
256 _eigenVector( 1, 2 ) = _eigenVector( 2, 1 ) = _m2[ 5 ];
259 _eigenValue = eigen.
doit( _eigenVector );
260 eigen.
sort( _eigenVector, _eigenValue );
264 template<
class T >
inline
269 out <<
"Image geometry: (" << mom.
cx() <<
"x" << mom.
cy() <<
"x" << mom.
cz();
270 out <<
")" << std::endl <<
"Volume : " << mom.
m0() <<
"mm3" << std::endl;
271 out <<
"Number of points : " << mom.
sum() << std::endl;
272 out <<
"Volume (mm3) : " << mom.
m0() << std::endl;
273 out <<
"Order 1 moments : ";
274 for ( i=0; i<3; i++ ) out << mom.
m1()[ i ] <<
" ";
275 out << std::endl <<
"Order 2 moments : ";
276 for ( i=0; i<6; i++ ) out << mom.
m2()[ i ] <<
" ";
277 out << std::endl <<
"Order 3 moments : ";
278 for ( i=0; i<10; i++ ) out << mom.
m3()[ i ] <<
" ";
279 out << std::endl <<
"Center of Mass : (" << mom.
gravity()[ 0 ] <<
",";
280 out << mom.
gravity()[ 1 ] <<
"," << mom.
gravity()[ 2 ] <<
")" << std::endl;
281 out <<
"Orientation :" << std::endl <<
" Inerty : ";
284 out << std::endl <<
" V1 : (" << mom.
eigenVector()( 0, 0 ) <<
",";
286 out << std::endl <<
" V2 : (" << mom.
eigenVector()( 0, 1 ) <<
",";
288 out << std::endl <<
" V3 : (" << mom.
eigenVector()( 0, 2 ) <<
",";
295 template<
class T >
inline
305 else if( m.
_sum == 0 )
308 double g0 = _m1[0] / _m0;
309 double g1 = _m1[1] / _m0;
310 double g2 = _m1[2] / _m0;
312 _m3[0] += _m0*g0*g0*g0 + g0*_m2[0]*3;
313 _m3[1] += _m0*g1*g1*g1 + g1*_m2[1]*3;
314 _m3[2] += _m0*g2*g2*g2 + g2*_m2[2]*3;
315 _m3[3] += _m0*g0*g0*g1 + g0*_m2[3]*2 + g1*_m2[0];
316 _m3[4] += _m0*g0*g0*g2 + g0*_m2[4]*2 + g2*_m2[0];
317 _m3[5] += _m0*g0*g1*g1 + g0*_m2[1] + g1*_m2[3]*2;
318 _m3[6] += _m0*g1*g1*g2 + g1*_m2[5]*2 + g2*_m2[1];
319 _m3[7] += _m0*g0*g2*g2 + g0*_m2[2] + g2*_m2[4]*2;
320 _m3[8] += _m0*g1*g2*g2 + g1*_m2[2] + g2*_m2[5]*2;
321 _m3[9] += _m0*g0*g1*g2 + g0*_m2[5] + g1*_m2[4] +g2*_m2[3];
323 _m2[0] += _m0 * g0*g0;
324 _m2[1] += _m0 * g1*g1;
325 _m2[2] += _m0 * g2*g2;
326 _m2[3] += _m0 * g0*g1;
327 _m2[4] += _m0 * g0*g2;
328 _m2[5] += _m0 * g1*g2;
330 double m20 = m.
_m2[0];
331 double m21 = m.
_m2[1];
332 double m22 = m.
_m2[2];
333 double m23 = m.
_m2[3];
334 double m24 = m.
_m2[4];
335 double m25 = m.
_m2[5];
337 double h0 = m.
_m1[0] / m.
_m0;
338 double h1 = m.
_m1[1] / m.
_m0;
339 double h2 = m.
_m1[2] / m.
_m0;
347 _m3[0] += m.
_m3[0] + m.
_m0*h0*h0*h0 + h0*m20*3;
348 _m3[1] += m.
_m3[1] + m.
_m0*h1*h1*h1 + h1*m21*3;
349 _m3[2] += m.
_m3[2] + m.
_m0*h2*h2*h2 + h2*m22*3;
350 _m3[3] += m.
_m3[3] + m.
_m0*h0*h0*h1 + h0*m23*2 + h1*m20;
351 _m3[4] += m.
_m3[4] + m.
_m0*h0*h0*h2 + h0*m24*2 + h2*m20;
352 _m3[5] += m.
_m3[5] + m.
_m0*h0*h1*h1 + h0*m21 + h1*m23*2;
353 _m3[6] += m.
_m3[6] + m.
_m0*h1*h1*h2 + h1*m25*2 + h2*m21;
354 _m3[7] += m.
_m3[7] + m.
_m0*h0*h2*h2 + h0*m22 + h2*m24*2;
355 _m3[8] += m.
_m3[8] + m.
_m0*h1*h2*h2 + h1*m22 + h2*m25*2;
356 _m3[9] += m.
_m3[9] + m.
_m0*h0*h1*h2 + h0*m25 + h1*m24 +h2*m23;
358 _m2[0] += m.
_m2[0] + m.
_m0 * h0*h0;
359 _m2[1] += m.
_m2[1] + m.
_m0 * h1*h1;
360 _m2[2] += m.
_m2[2] + m.
_m0 * h2*h2;
361 _m2[3] += m.
_m2[3] + m.
_m0 * h0*h1;
362 _m2[4] += m.
_m2[4] + m.
_m0 * h0*h2;
363 _m2[5] += m.
_m2[5] + m.
_m0 * h1*h2;
367 _g[0] = _m1[0] / _m0;
368 _g[1] = _m1[1] / _m0;
369 _g[2] = _m1[2] / _m0;
376 _m2[0] -= _m0 * g0*g0;
377 _m2[1] -= _m0 * g1*g1;
378 _m2[2] -= _m0 * g2*g2;
379 _m2[3] -= _m0 * g0*g1;
380 _m2[4] -= _m0 * g0*g2;
381 _m2[5] -= _m0 * g1*g2;
383 _m3[0] -= _m0*g0*g0*g0 + g0*_m2[0]*3;
384 _m3[1] -= _m0*g1*g1*g1 + g1*_m2[1]*3;
385 _m3[2] -= _m0*g2*g2*g2 + g2*_m2[2]*3;
386 _m3[3] -= _m0*g0*g0*g1 + g0*_m2[3]*2 + g1*_m2[0];
387 _m3[4] -= _m0*g0*g0*g2 + g0*_m2[4]*2 + g2*_m2[0];
388 _m3[5] -= _m0*g0*g1*g1 + g0*_m2[1] + g1*_m2[3]*2;
389 _m3[6] -= _m0*g1*g1*g2 + g1*_m2[5]*2 + g2*_m2[1];
390 _m3[7] -= _m0*g0*g2*g2 + g0*_m2[2] + g2*_m2[4]*2;
391 _m3[8] -= _m0*g1*g2*g2 + g1*_m2[2] + g2*_m2[5]*2;
392 _m3[9] -= _m0*g0*g1*g2 + g0*_m2[5] + g1*_m2[4] +g2*_m2[3];
399 template<
class T >
inline
408 #pragma GCC diagnostic push
409 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
413 std::clog <<
"PROGRAMMING ERROR: called unimplemented base method"
414 " Moment<T>::doit( VolumeRef< T >&, T, int )"
417 throw std::logic_error(
"called unimplemented base method"
418 " Moment<T>::doit( VolumeRef< T >&, T, int )");
425 std::clog <<
"PROGRAMMING ERROR: called unimplemented base method"
426 " Moment<T>::doit( AimsSurfaceTriangle& )"
429 throw std::logic_error(
"called unimplemented base method"
430 " Moment<T>::doit( AimsSurfaceTriangle& )");
437 std::clog <<
"PROGRAMMING ERROR: called unimplemented base method"
438 " Moment<T>::doit( const aims::BucketMap<Void> & )"
441 throw std::logic_error(
"called unimplemented base method"
442 " Moment<T>::doit( const aims::BucketMap<Void> & )");
445 #pragma GCC diagnostic pop
void sort(carto::VolumeRef< T > eigenvectors, carto::VolumeRef< T > eigenvalues, carto::VolumeRef< T > *wi=NULL)
Sort the eigenvectors and eigenvalues in decreasing order.
carto::VolumeRef< T > doit(carto::VolumeRef< T >, carto::VolumeRef< T > *wi=NULL)
Eigen system resolution function.
carto::VolumeRef< double > _eigenValue
virtual void update(AimsVector< double, 3 > &, int)
virtual void doit(const aims::BucketMap< Void > &)
Moment< T > & operator+=(const Moment< T > &)
const carto::VolumeRef< double > & eigenVector() const
Moment(const Moment< T > &)
const double * m1() const
carto::VolumeRef< double > _eigenVector
virtual void orientation()
const double * m3() const
virtual void doit(AimsSurfaceTriangle &)
const carto::VolumeRef< double > & eigenValue() const
const double & sum() const
const double & m0() const
virtual void doit(carto::rc_ptr< carto::Volume< T > > &, T, int)
const double * m2() const
Moment()
doesn't necessarily clear all moments to 0. Call clear() to be sure
virtual void update(Point3df &, int)
Moment< T > operator+(const Moment< T > &)
virtual void update(double, double, double, int)
const double * gravity() const
std::ostream & operator<<(std::ostream &, const Moment< T > &)
DataTypeTraits< T >::LongType sum(const Volume< T > &vol)
AIMSDATA_API AimsTimeSurface< 3, Void > AimsSurfaceTriangle