Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_SIGNED_DISTANCE_TO_TRIANGLE_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_COMPUTE_SIGNED_DISTANCE_TO_TRIANGLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace geometry
00015 {
00035 template<typename vector3_type>
00036 typename vector3_type::value_type
00037 compute_signed_distance_to_triangle(
00038 vector3_type const & p
00039 , vector3_type const & pi
00040 , vector3_type const & pj
00041 , vector3_type const & pk
00042 , vector3_type const & nv_i
00043 , vector3_type const & nv_j
00044 , vector3_type const & nv_k
00045 , vector3_type const & ne_i
00046 , vector3_type const & ne_j
00047 , vector3_type const & ne_k
00048 )
00049 {
00050 typedef typename vector3_type::value_type real_type;
00051 typedef typename vector3_type::value_traits value_traits;
00052
00053 vector3_type ei = unit( pk-pj );
00054 vector3_type ej = unit( pi-pk );
00055 vector3_type ek = unit( pj-pi );
00056
00057 vector3_type n = - unit( cross( ei, ek ) );
00058 vector3_type ni = cross( n, ei);
00059 vector3_type nj = cross( n, ej);
00060 vector3_type nk = cross( n, ek);
00061
00062 vector3_type delta_i = ( p-pi );
00063 vector3_type delta_j = ( p-pj );
00064 vector3_type delta_k = ( p-pk );
00065
00066 real_type di = inner_prod(ni,delta_j);
00067 real_type dj = inner_prod(nj,delta_k);
00068 real_type dk = inner_prod(nk,delta_i);
00069
00070 if(di>=value_traits::zero() && dj>=value_traits::zero() && dk>=value_traits::zero())
00071 {
00072 return inner_prod(n, delta_i );
00073 }
00074 else if(di<value_traits::zero())
00075 {
00076 real_type tst_j = inner_prod(ei, delta_j);
00077 real_type tst_k = - inner_prod(ei, delta_k);
00078 if(tst_j<value_traits::zero())
00079 {
00080 real_type sign = inner_prod(nv_j,delta_j) >=value_traits::zero() ? value_traits::one() : -value_traits::one();
00081 return sign*length(delta_j);
00082 }
00083 if(tst_k<value_traits::zero())
00084 {
00085 real_type sign = inner_prod(nv_k,delta_k) >= value_traits::zero() ? value_traits::one() : -value_traits::one();
00086 return sign*length(delta_k);
00087 }
00088
00089 vector3_type orthogonal = delta_j - inner_prod(ei,delta_j)*ei;
00090 real_type sign = inner_prod(ne_i,orthogonal)>=value_traits::zero() ? value_traits::one() : -value_traits::one();
00091
00092 return sign*length( orthogonal );
00093 }
00094 else if(dj<value_traits::zero())
00095 {
00096 real_type tst_k = inner_prod(ej, delta_k);
00097 real_type tst_i = - inner_prod(ej, delta_i);
00098 if(tst_k<value_traits::zero())
00099 {
00100 real_type sign = inner_prod(nv_k,delta_k) >=value_traits::zero() ? value_traits::one() : -value_traits::one();
00101 return sign*length(delta_k);
00102 }
00103 if(tst_i<value_traits::zero())
00104 {
00105 real_type sign = inner_prod(nv_i,delta_i) >=value_traits::zero() ? value_traits::one() : -value_traits::one();
00106 return sign*length(delta_i);
00107 }
00108
00109 vector3_type orthogonal = delta_k - inner_prod(ej,delta_k)*ej;
00110 real_type sign = inner_prod(ne_j,orthogonal)>=value_traits::zero() ? value_traits::one() : -value_traits::one();
00111
00112 return sign*length( orthogonal );
00113 }
00114 else if(dk<value_traits::zero())
00115 {
00116 real_type tst_i = inner_prod(ek, delta_i);
00117 real_type tst_j = - inner_prod(ek, delta_j);
00118 if(tst_i<value_traits::zero())
00119 {
00120 real_type sign = inner_prod(nv_i,delta_i) >=value_traits::zero() ? value_traits::one() : -value_traits::one();
00121 return sign*length(delta_i);
00122 }
00123 if(tst_j<value_traits::zero())
00124 {
00125 real_type sign = inner_prod(nv_j,delta_j) >=value_traits::zero() ? value_traits::one() : -value_traits::one();
00126 return sign*length(delta_j);
00127 }
00128
00129 vector3_type orthogonal = delta_i - inner_prod(ek,delta_i)*ek;
00130 real_type sign = inner_prod(ne_k,orthogonal)>=value_traits::zero() ? value_traits::one() : -value_traits::one();
00131
00132 return sign*length( orthogonal );
00133 }
00134
00135 assert( false || !"compute_signed_distance_to_triangle(): internal error case analysis failed?");
00136 return value_traits::zero();
00137 }
00138
00139 }
00140 }
00141
00142
00143 #endif