Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_DISTANCE_TO_TRIANGLE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_DISTANCE_TO_TRIANGLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <cmath>
00013
00014 namespace OpenTissue
00015 {
00016 namespace geometry
00017 {
00018
00030 template<typename vector3_type>
00031 typename vector3_type::value_type
00032 compute_distance_to_triangle(
00033 vector3_type const & p
00034 , vector3_type const & pi
00035 , vector3_type const & pj
00036 , vector3_type const & pk
00037 )
00038 {
00039 using std::fabs;
00040
00041 typedef typename vector3_type::value_type real_type;
00042 typedef typename vector3_type::value_traits value_traits;
00043
00044 vector3_type ei = unit( pk-pj );
00045 vector3_type ej = unit( pi-pk );
00046 vector3_type ek = unit( pj-pi );
00047
00048 vector3_type n = - unit( cross( ei, ek ) );
00049 vector3_type ni = cross( n, ei);
00050 vector3_type nj = cross( n, ej);
00051 vector3_type nk = cross( n, ek);
00052
00053 vector3_type delta_i = ( p-pi );
00054 vector3_type delta_j = ( p-pj );
00055 vector3_type delta_k = ( p-pk );
00056
00057 real_type di = inner_prod(ni,delta_j);
00058 real_type dj = inner_prod(nj,delta_k);
00059 real_type dk = inner_prod(nk,delta_i);
00060
00061 if(di>=value_traits::zero() && dj>=value_traits::zero() && dk>=value_traits::zero())
00062 {
00063 return fabs( inner_prod(n, delta_i ) );
00064 }
00065 else if(di<value_traits::zero())
00066 {
00067 real_type tst_j = inner_prod(ei, delta_j);
00068 real_type tst_k = - inner_prod(ei, delta_k);
00069 if(tst_j<value_traits::zero())
00070 return length(delta_j);
00071 if(tst_k<value_traits::zero())
00072 return length(delta_k);
00073
00074 vector3_type orthogonal = delta_j - inner_prod(ei,delta_j)*ei;
00075
00076 return length( orthogonal );
00077 }
00078 else if(dj<value_traits::zero())
00079 {
00080 real_type tst_k = inner_prod(ej, delta_k);
00081 real_type tst_i = - inner_prod(ej, delta_i);
00082 if(tst_k<value_traits::zero())
00083 return length(delta_k);
00084 if(tst_i<value_traits::zero())
00085 return length(delta_i);
00086
00087 vector3_type orthogonal = delta_k - inner_prod(ej,delta_k)*ej;
00088
00089 return length( orthogonal );
00090 }
00091 else if(dk<value_traits::zero())
00092 {
00093 real_type tst_i = inner_prod(ek, delta_i);
00094 real_type tst_j = - inner_prod(ek, delta_j);
00095 if(tst_i<value_traits::zero())
00096 return length(delta_i);
00097 if(tst_j<value_traits::zero())
00098 return length(delta_j);
00099
00100 vector3_type orthogonal = delta_i - inner_prod(ek,delta_i)*ek;
00101
00102 return length( orthogonal );
00103 }
00104
00105 assert(false || !"compute_distance_to_triangle(): internal error case analysis failed?");
00106
00107 return value_traits::zero();
00108 }
00109
00110 }
00111 }
00112
00113
00114 #endif