00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TETRAHEDRON_H
00002 #define OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TETRAHEDRON_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/geometry_barycentric.h>
00013
00014 #include <OpenTissue/collision/gjk/gjk_simplex.h>
00015 #include <OpenTissue/collision/gjk/gjk_outside_triangle.h>
00016 #include <OpenTissue/collision/gjk/gjk_outside_vertex_edge_voronoi_plane.h>
00017 #include <OpenTissue/collision/gjk/gjk_outside_edge_face_voronoi_plane.h>
00018
00019 #include <cmath>
00020
00021 namespace OpenTissue
00022 {
00023 namespace gjk
00024 {
00025
00026 namespace detail
00027 {
00041 template< typename V >
00042 inline void reduce_tetrahedron( V const & p, Simplex<V> & S)
00043 {
00044 typedef typename V::value_type T;
00045 typedef typename V::value_traits value_traits;
00046
00047 size_t const idx_A = 0u;
00048 size_t const idx_B = 1u;
00049 size_t const idx_C = 2u;
00050 size_t const idx_D = 3u;
00051
00052 int const bit_A = 1;
00053 int const bit_B = 2;
00054 int const bit_C = 4;
00055 int const bit_D = 8;
00056
00057 V const & A = S.m_v[idx_A];
00058 V const & B = S.m_v[idx_B];
00059 V const & C = S.m_v[idx_C];
00060 V const & D = S.m_v[idx_D];
00061
00062 bool const outside_AB = outside_vertex_edge_voronoi_plane(p, A, B);
00063 bool const outside_AC = outside_vertex_edge_voronoi_plane(p, A, C);
00064 bool const outside_AD = outside_vertex_edge_voronoi_plane(p, A, D);
00065 bool const outside_BA = outside_vertex_edge_voronoi_plane(p, B, A);
00066 bool const outside_BC = outside_vertex_edge_voronoi_plane(p, B, C);
00067 bool const outside_BD = outside_vertex_edge_voronoi_plane(p, B, D);
00068 bool const outside_CA = outside_vertex_edge_voronoi_plane(p, C, A);
00069 bool const outside_CB = outside_vertex_edge_voronoi_plane(p, C, B);
00070 bool const outside_CD = outside_vertex_edge_voronoi_plane(p, C, D);
00071 bool const outside_DA = outside_vertex_edge_voronoi_plane(p, D, A);
00072 bool const outside_DB = outside_vertex_edge_voronoi_plane(p, D, B);
00073 bool const outside_DC = outside_vertex_edge_voronoi_plane(p, D, C);
00074 bool const outside_ABC_vp = outside_edge_face_voronoi_plane( p, A, B, C);
00075 bool const outside_ABD_vp = outside_edge_face_voronoi_plane( p, A, B, D);
00076 bool const outside_CAB_vp = outside_edge_face_voronoi_plane( p, C, A, B);
00077 bool const outside_CAD_vp = outside_edge_face_voronoi_plane( p, C, A, D);
00078 bool const outside_DAB_vp = outside_edge_face_voronoi_plane( p, D, A, B);
00079 bool const outside_ADC_vp = outside_edge_face_voronoi_plane( p, A, D, C);
00080 bool const outside_BCA_vp = outside_edge_face_voronoi_plane( p, B, C, A);
00081 bool const outside_BCD_vp = outside_edge_face_voronoi_plane( p, B, C, D);
00082 bool const outside_BDA_vp = outside_edge_face_voronoi_plane( p, B, D, A);
00083 bool const outside_DBC_vp = outside_edge_face_voronoi_plane( p, D, B, C);
00084 bool const outside_CDB_vp = outside_edge_face_voronoi_plane( p, C, D, B);
00085 bool const outside_DCA_vp = outside_edge_face_voronoi_plane( p, D, C, A);
00086 bool const outside_ABC = outside_triangle( p, A, B, C, D);
00087 bool const outside_ABD = outside_triangle( p, A, B, D, C);
00088 bool const outside_BCD = outside_triangle( p, B, C, D, A);
00089 bool const outside_CAD = outside_triangle( p, C, A, D, B);
00090
00091
00092 if( outside_AB && outside_AC && outside_AD)
00093 {
00094 S.m_bitmask = bit_A;
00095 S.m_v[idx_B].clear();
00096 S.m_v[idx_C].clear();
00097 S.m_v[idx_D].clear();
00098 S.m_a[idx_B].clear();
00099 S.m_a[idx_C].clear();
00100 S.m_a[idx_D].clear();
00101 S.m_b[idx_B].clear();
00102 S.m_b[idx_C].clear();
00103 S.m_b[idx_D].clear();
00104 S.m_w[idx_A] = value_traits::one();
00105 S.m_w[idx_B] = value_traits::zero();
00106 S.m_w[idx_C] = value_traits::zero();
00107 S.m_w[idx_D] = value_traits::zero();
00108 return;
00109 }
00110 if( outside_BA && outside_BC && outside_BD)
00111 {
00112 S.m_bitmask = bit_B;
00113 S.m_v[idx_A].clear();
00114 S.m_v[idx_C].clear();
00115 S.m_v[idx_D].clear();
00116 S.m_a[idx_A].clear();
00117 S.m_a[idx_C].clear();
00118 S.m_a[idx_D].clear();
00119 S.m_b[idx_A].clear();
00120 S.m_b[idx_C].clear();
00121 S.m_b[idx_D].clear();
00122 S.m_w[idx_A] = value_traits::zero();
00123 S.m_w[idx_B] = value_traits::one();
00124 S.m_w[idx_C] = value_traits::zero();
00125 S.m_w[idx_D] = value_traits::zero();
00126 return;
00127 }
00128 if( outside_CA && outside_CB && outside_CD)
00129 {
00130 S.m_bitmask = bit_C;
00131 S.m_v[idx_A].clear();
00132 S.m_v[idx_B].clear();
00133 S.m_v[idx_D].clear();
00134 S.m_a[idx_A].clear();
00135 S.m_a[idx_B].clear();
00136 S.m_a[idx_D].clear();
00137 S.m_b[idx_A].clear();
00138 S.m_b[idx_B].clear();
00139 S.m_b[idx_D].clear();
00140 S.m_w[idx_A] = value_traits::zero();
00141 S.m_w[idx_B] = value_traits::zero();
00142 S.m_w[idx_C] = value_traits::one();
00143 S.m_w[idx_D] = value_traits::zero();
00144 return;
00145 }
00146 if( outside_DA && outside_DB && outside_DC)
00147 {
00148 S.m_bitmask = bit_D;
00149 S.m_v[idx_A].clear();
00150 S.m_v[idx_B].clear();
00151 S.m_v[idx_C].clear();
00152 S.m_a[idx_A].clear();
00153 S.m_a[idx_B].clear();
00154 S.m_a[idx_C].clear();
00155 S.m_b[idx_A].clear();
00156 S.m_b[idx_B].clear();
00157 S.m_b[idx_C].clear();
00158 S.m_w[idx_A] = value_traits::zero();
00159 S.m_w[idx_B] = value_traits::zero();
00160 S.m_w[idx_C] = value_traits::zero();
00161 S.m_w[idx_D] = value_traits::one();
00162 return;
00163 }
00164
00165
00166 if(outside_ABC_vp && outside_ABD_vp && !outside_AB && !outside_BA)
00167 {
00168 S.m_bitmask = bit_A | bit_B;
00169 S.m_v[idx_C].clear();
00170 S.m_v[idx_D].clear();
00171 S.m_a[idx_C].clear();
00172 S.m_a[idx_D].clear();
00173 S.m_b[idx_C].clear();
00174 S.m_b[idx_D].clear();
00175 S.m_w[idx_C] = value_traits::zero();
00176 S.m_w[idx_D] = value_traits::zero();
00177 OpenTissue::geometry::barycentric_geometric(A,B,p,S.m_w[idx_A],S.m_w[idx_B]);
00178 return;
00179 }
00180 if(outside_CAB_vp && outside_CAD_vp && !outside_CA && !outside_AC)
00181 {
00182 S.m_bitmask = bit_A | bit_C;
00183 S.m_v[idx_B].clear();
00184 S.m_v[idx_D].clear();
00185 S.m_a[idx_B].clear();
00186 S.m_a[idx_D].clear();
00187 S.m_b[idx_B].clear();
00188 S.m_b[idx_D].clear();
00189 S.m_w[idx_B] = value_traits::zero();
00190 S.m_w[idx_D] = value_traits::zero();
00191 OpenTissue::geometry::barycentric_geometric(A,C,p,S.m_w[idx_A],S.m_w[idx_C]);
00192 return;
00193 }
00194 if(outside_DAB_vp && outside_ADC_vp && !outside_AD && !outside_DA)
00195 {
00196 S.m_bitmask = bit_A | bit_D;
00197 S.m_v[idx_B].clear();
00198 S.m_v[idx_C].clear();
00199 S.m_a[idx_B].clear();
00200 S.m_a[idx_C].clear();
00201 S.m_b[idx_B].clear();
00202 S.m_b[idx_C].clear();
00203 S.m_w[idx_B] = value_traits::zero();
00204 S.m_w[idx_C] = value_traits::zero();
00205 OpenTissue::geometry::barycentric_geometric(A,D,p,S.m_w[idx_A],S.m_w[idx_D]);
00206 return;
00207 }
00208 if(outside_BCA_vp && outside_BCD_vp && !outside_BC && !outside_CB)
00209 {
00210 S.m_bitmask = bit_B | bit_C;
00211 S.m_v[idx_A].clear();
00212 S.m_v[idx_D].clear();
00213 S.m_a[idx_A].clear();
00214 S.m_a[idx_D].clear();
00215 S.m_b[idx_A].clear();
00216 S.m_b[idx_D].clear();
00217 S.m_w[idx_A] = value_traits::zero();
00218 S.m_w[idx_D] = value_traits::zero();
00219 OpenTissue::geometry::barycentric_geometric(B,C,p,S.m_w[idx_B],S.m_w[idx_C]);
00220 return;
00221 }
00222 if(outside_BDA_vp && outside_DBC_vp && !outside_BD && !outside_DB)
00223 {
00224 S.m_bitmask = bit_B | bit_D;
00225 S.m_v[idx_A].clear();
00226 S.m_v[idx_C].clear();
00227 S.m_a[idx_A].clear();
00228 S.m_a[idx_C].clear();
00229 S.m_b[idx_A].clear();
00230 S.m_b[idx_C].clear();
00231 S.m_w[idx_A] = value_traits::zero();
00232 S.m_w[idx_C] = value_traits::zero();
00233 OpenTissue::geometry::barycentric_geometric(B,D,p,S.m_w[idx_B],S.m_w[idx_D]);
00234 return;
00235 }
00236 if(outside_CDB_vp && outside_DCA_vp && !outside_CD && !outside_DC)
00237 {
00238 S.m_bitmask = bit_C | bit_D;
00239 S.m_v[idx_A].clear();
00240 S.m_v[idx_B].clear();
00241 S.m_a[idx_A].clear();
00242 S.m_a[idx_B].clear();
00243 S.m_b[idx_A].clear();
00244 S.m_b[idx_B].clear();
00245 S.m_w[idx_A] = value_traits::zero();
00246 S.m_w[idx_B] = value_traits::zero();
00247 OpenTissue::geometry::barycentric_geometric(C,D,p,S.m_w[idx_C],S.m_w[idx_D]);
00248 return;
00249 }
00250
00251
00252 if (outside_ABC && !outside_ABC_vp && !outside_BCA_vp && !outside_CAB_vp)
00253 {
00254 S.m_bitmask = bit_A | bit_B | bit_C;
00255 S.m_v[idx_D].clear();
00256 S.m_a[idx_D].clear();
00257 S.m_b[idx_D].clear();
00258 S.m_w[idx_D] = value_traits::zero();
00259 OpenTissue::geometry::barycentric_geometric( A, B, C, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_C]);
00260 return;
00261 }
00262 if (outside_ABD && !outside_ABD_vp && !outside_BDA_vp && !outside_DAB_vp)
00263 {
00264 S.m_bitmask = bit_A | bit_B | bit_D;
00265 S.m_v[idx_C].clear();
00266 S.m_a[idx_C].clear();
00267 S.m_b[idx_C].clear();
00268 S.m_w[idx_C] = value_traits::zero();
00269 OpenTissue::geometry::barycentric_geometric( A, B, D, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_D]);
00270 return;
00271 }
00272 if (outside_BCD && !outside_BCD_vp && !outside_CDB_vp && !outside_DBC_vp)
00273 {
00274 S.m_bitmask = bit_B | bit_C | bit_D;
00275 S.m_v[idx_A].clear();
00276 S.m_a[idx_A].clear();
00277 S.m_b[idx_A].clear();
00278 S.m_w[idx_A] = value_traits::zero();
00279 OpenTissue::geometry::barycentric_geometric( B, C, D, p, S.m_w[idx_B], S.m_w[idx_C], S.m_w[idx_D]);
00280 return;
00281 }
00282 if (outside_CAD && !outside_CAD_vp && !outside_ADC_vp && !outside_DCA_vp)
00283 {
00284 S.m_bitmask = bit_C | bit_A | bit_D;
00285 S.m_v[idx_B].clear();
00286 S.m_a[idx_B].clear();
00287 S.m_b[idx_B].clear();
00288 S.m_w[idx_B] = value_traits::zero();
00289 OpenTissue::geometry::barycentric_geometric( C, A, D, p, S.m_w[idx_C], S.m_w[idx_A], S.m_w[idx_D]);
00290 return;
00291 }
00292
00293
00294 if( !outside_ABC && !outside_ABD && !outside_BCD && !outside_CAD)
00295 {
00296 OpenTissue::geometry::barycentric_geometric( A, B, C, D, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_C], S.m_w[idx_D]);
00297 return;
00298 }
00299 }
00300
00301
00302 }
00303
00304 }
00305
00306 }
00307
00308
00309 #endif