Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_VOLUME_LENGTH_QUALITY_MEASURE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_VOLUME_LENGTH_QUALITY_MEASURE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_is_number.h>
00013 #include <OpenTissue/core/math/math_basic_types.h>
00014 #include <OpenTissue/core/geometry/geometry_tetrahedron.h>
00015
00016 #include <boost/cast.hpp>
00017
00018 #include <cmath>
00019 #include <cassert>
00020
00021 namespace OpenTissue
00022 {
00023 namespace geometry
00024 {
00044 template<typename vector3_type>
00045 inline typename vector3_type::value_type
00046 compute_volume_length_quality_measure (
00047 vector3_type const & p0
00048 , vector3_type const & p1
00049 , vector3_type const & p2
00050 , vector3_type const & p3
00051 )
00052 {
00053 using std::pow;
00054 using std::fabs;
00055
00056 typedef typename vector3_type::value_type real_type;
00057 typedef OpenTissue::math::BasicMathTypes<real_type, size_t> math_types;
00058 typedef typename math_types::value_traits value_traits;
00059 typedef Tetrahedron<math_types> tetrahedron_type;
00060
00061 vector3_type e0 = (p0-p1);
00062 vector3_type e1 = (p1-p2);
00063 vector3_type e2 = (p2-p0);
00064 vector3_type e3 = (p0-p3);
00065 vector3_type e4 = (p1-p3);
00066 vector3_type e5 = (p2-p3);
00067 real_type l0 = inner_prod(e0,e0);
00068 real_type l1 = inner_prod(e1,e1);
00069 real_type l2 = inner_prod(e2,e2);
00070 real_type l3 = inner_prod(e3,e3);
00071 real_type l4 = inner_prod(e4,e4);
00072 real_type l5 = inner_prod(e5,e5);
00073 real_type denom = l0 + l1 + l2 + l3 + l4 + l5;
00074
00075 if ( denom == value_traits::zero() )
00076 return value_traits::zero();
00077
00078 tetrahedron_type T(p0,p1,p2,p3);
00079
00080 real_type const exponent = boost::numeric_cast<real_type>( 2.0 / 3.0 );
00081 real_type base = boost::numeric_cast<real_type>( 3.0 * fabs( T.volume() ) );
00082 real_type nominator = boost::numeric_cast<real_type>(12.0 * pow (base , exponent ));
00083 real_type quality = nominator / denom;
00084 assert( is_number( base ) || !"base was not a number" );
00085 assert( base >= value_traits::zero() || !"base must be non-negative" );
00086 assert( is_number( nominator ) || !"nominator was not a number" );
00087 assert( nominator >= value_traits::zero() || !"nominator must be non-negative" );
00088 assert( is_number( denom ) || !"denom was not a number" );
00089 assert( denom > value_traits::zero() || !"denom must be positive" );
00090 assert( is_number( quality ) || !"quality was not a number" );
00091 assert( quality>= value_traits::zero() || !"invalid qualtiy value" );
00092 assert( quality<= value_traits::one() || !"invalid qualtiy value" );
00093 return quality;
00094 };
00095
00096 }
00097
00098 }
00099
00100
00101 #endif