Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_SIGNED_DISTANCE_TO_TRIANGLE_H
00002 #define OPENTISSUE_COLLISION_GJK_GJK_SIGNED_DISTANCE_TO_TRIANGLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_is_number.h>
00013
00014 #include <cmath>
00015 #include <cassert>
00016
00017 namespace OpenTissue
00018 {
00019 namespace gjk
00020 {
00021 namespace detail
00022 {
00023
00037 template< typename V >
00038 inline typename V::value_type signed_distance_to_triangle(
00039 V const & p
00040 , V const & A
00041 , V const & B
00042 , V const & C
00043 , V const & q
00044 )
00045 {
00046 using std::fabs;
00047
00048 typedef typename V::value_traits value_traits;
00049 typedef typename V::value_type T;
00050
00051 V m = cross( A-B, C-B );
00052
00053 assert( dot( m, m ) > value_traits::zero() || !"signed_distance_to_triangle(): Degenerate triangle encountered");
00054
00055 V n = unit( m );
00056
00057 T sign_p = dot( n, p-B );
00058 T sign_q = dot( n, q-B );
00059 T abs_p = fabs( sign_p );
00060
00061 assert( sign_q < value_traits::zero() || sign_q > value_traits::zero() || !"signed_distance_to_triangle(): q was in plane, can not be used to determine sign");
00062
00063 assert( is_number( sign_p ) || !"signed_distance_to_triangle(): Not a Number encountered");
00064 assert( is_number( sign_q ) || !"signed_distance_to_triangle(): Not a Number encountered");
00065 assert( is_number( abs_p ) || !"signed_distance_to_triangle(): Not a Number encountered");
00066
00067 bool in_front = ( (sign_p*sign_q) <= value_traits::zero() );
00068
00069 return in_front ? abs_p : - abs_p;
00070 }
00071
00072 }
00073
00074 }
00075
00076 }
00077
00078
00079 #endif