00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 #ifndef __VCG_TETRA3
00122 #define __VCG_TETRA3
00123
00124 #include <vcg/space/point3.h>
00125 #include <vcg/math/matrix44.h>
00126 #include <vcg/math/matrix33.h>
00127
00128 #include <algorithm>
00129
00130 namespace vcg {
00138 class Tetra
00139 {
00140 public:
00141
00142
00143
00144
00145 static int VofE(const int &indexE,const int &indexV)
00146 { assert ((indexE<6)&&(indexV<2));
00147 static int edgevert[6][2] ={{0,1},
00148 {0,2},
00149 {0,3},
00150 {1,2},
00151 {1,3},
00152 {2,3}};
00153 return (edgevert[indexE][indexV]);
00154 }
00155
00156 static int VofF(const int &indexF,const int &indexV)
00157 { assert ((indexF<4)&&(indexV<3));
00158 static int facevert[4][3]={{0,1,2},
00159 {0,3,1},
00160 {0,2,3},
00161 {1,3,2}};
00162 return (facevert[indexF][indexV]);
00163 }
00164
00165 static int EofV(const int &indexV,const int &indexE)
00166 {
00167 assert ((indexE<3)&&(indexV<4));
00168 static int vertedge[4][3]={{0,1,2},
00169 {0,3,4},
00170 {5,1,3},
00171 {4,5,2}};
00172 return vertedge[indexV][indexE];
00173 }
00174
00175 static int EofF(const int &indexF,const int &indexE)
00176 { assert ((indexF<4)&&(indexE<3));
00177 static int faceedge[4][3]={{0,3,1},
00178 {2,4,0},
00179 {1,5,2},
00180 {4,5,3}
00181 };
00182 return faceedge [indexF][indexE];
00183 }
00184
00185 static int FofV(const int &indexV,const int &indexF)
00186 {
00187 assert ((indexV<4)&&(indexF<3));
00188 static int vertface[4][3]={{0,1,2},
00189 {0,3,1},
00190 {0,2,3},
00191 {1,3,2}};
00192 return vertface[indexV][indexF];
00193 }
00194
00195 static int FofE(const int &indexE,const int &indexSide)
00196 { assert ((indexE<6)&&(indexSide<2));
00197 static int edgeface[6][2]={{0,1},
00198 {0,2},
00199 {1,2},
00200 {0,3},
00201 {1,3},
00202 {2,3}};
00203 return edgeface [indexE][indexSide];
00204 }
00205
00206 static int VofEE(const int &indexE0,const int &indexE1)
00207 {
00208 assert ((indexE0<6)&&(indexE0>=0));
00209 assert ((indexE1<6)&&(indexE1>=0));
00210 static int edgesvert[6][6]={{-1,0,0,1,1,-1},
00211 {0,-1,0,2,-1,2},
00212 {0,0,-1,-1,3,3},
00213 {1,2,-1,-1,1,2},
00214 {1,-1,3,1,-1,3},
00215 {-1,2,3,2,3,-1}};
00216 return (edgesvert[indexE0][indexE1]);
00217 }
00218
00219 static int VofFFF(const int &indexF0,const int &indexF1,const int &indexF2)
00220 {
00221 assert ((indexF0<4)&&(indexF0>=0));
00222 assert ((indexF1<4)&&(indexF1>=0));
00223 assert ((indexF2<4)&&(indexF2>=0));
00224 static int facesvert[4][4][4]={
00225 {
00226 {-1,-1,-1,-1},{-1,-1,0,1},{-1,0,-1,2},{-1,1,2,-1}
00227 },
00228 {
00229 {-1,-1,0,1},{-1,-1,-1,-1},{0,-1,-1,3},{1,-1,3,-1}
00230 },
00231 {
00232 {-1,0,-1,2},{0,-1,-1,3},{-1,-1,-1,-1},{2,3,-1,-1}
00233 },
00234 {
00235 {-1,1,2,-1},{1,-1,3,-1},{2,3,-1,-1},{-1,-1,-1,-1}
00236 }
00237 };
00238 return facesvert[indexF0][indexF1][indexF2];
00239 }
00240
00241 static int EofFF(const int &indexF0,const int &indexF1)
00242 {
00243 assert ((indexF0<4)&&(indexF0>=0));
00244 assert ((indexF1<4)&&(indexF1>=0));
00245 static int facesedge[4][4]={{-1, 0, 1, 3},
00246 { 0, -1, 2, 4},
00247 { 1, 2, -1, 5},
00248 { 3, 4, 5, -1}};
00249 return (facesedge[indexF0][indexF1]);
00250 }
00251
00252 static int EofVV(const int &indexV0,const int &indexV1)
00253 {
00254 assert ((indexV0<4)&&(indexV0>=0));
00255 assert ((indexV1<4)&&(indexV1>=0));
00256 static int verticesedge[4][4]={{-1, 0, 1, 2},
00257 { 0, -1, 3, 4},
00258 { 1, 3, -1, 5},
00259 { 2, 4, 5, -1}};
00260
00261 return verticesedge[indexV0][indexV1];
00262 }
00263
00264 static int FofVVV(const int &indexV0,const int &indexV1,const int &indexV2)
00265 {
00266
00267 assert ((indexV0<4)&&(indexV0>=0));
00268 assert ((indexV1<4)&&(indexV1>=0));
00269 assert ((indexV2<4)&&(indexV2>=0));
00270
00271 static int verticesface[4][4][4]={
00272 {
00273 {-1,-1,-1,-1},{-1,-1,0,1},{-1,0,-1,2},{-1,1,2,-1}
00274 },
00275 {
00276 {-1,-1,0,1},{-1,-1,-1,-1},{0,-1,-1,3},{1,-1,3,-1}
00277 },
00278 {
00279 {-1,0,-1,2},{0,-1,-1,3},{-1,-1,-1,-1},{2,3,-1,-1}
00280 },
00281 {
00282 {-1,1,2,-1},{1,-1,3,-1},{2,3,-1,-1},{-1,-1,-1,-1}
00283 }
00284 };
00285 return verticesface[indexV0][indexV1][indexV2];
00286 }
00287
00288 static int FofEE(const int &indexE0,const int &indexE1)
00289 {
00290 assert ((indexE0<6)&&(indexE0>=0));
00291 assert ((indexE1<6)&&(indexE1>=0));
00292 static int edgesface[6][6]={{-1,0,1,0,1,-1},
00293 {0,-1,2,0,-1,2},
00294 {1,2,-1,-1,1,2},
00295 {0,0,-1,-1,3,3},
00296 {1,-1,1,3,-1,3},
00297 {-1,2,2,3,3,-1}};
00298
00299 return edgesface[indexE0][indexE1];
00300 }
00301 };
00302
00307 template <class ScalarType>
00308 class Tetra3:public Tetra
00309 {
00310 public:
00311 typedef Point3< ScalarType > CoordType;
00312
00313
00314
00315
00316
00317
00318 private:
00320 CoordType _v[4];
00321
00322 public:
00323
00325 inline CoordType & P( const int j ) { return _v[j];}
00326 inline CoordType const & cP( const int j )const { return _v[j];}
00327
00328 inline CoordType & P0( const int j ) { return _v[j];}
00329 inline CoordType & P1( const int j ) { return _v[(j+1)%4];}
00330 inline CoordType & P2( const int j ) { return _v[(j+2)%4];}
00331 inline CoordType & P3( const int j ) { return _v[(j+3)%4];}
00332
00333 inline const CoordType & P0( const int j ) const { return _v[j];}
00334 inline const CoordType & P1( const int j ) const { return _v[(j+1)%4];}
00335 inline const CoordType & P2( const int j ) const { return _v[(j+2)%4];}
00336 inline const CoordType & P3( const int j ) const { return _v[(j+3)%4];}
00337
00338 inline const CoordType & cP0( const int j ) const { return _v[j];}
00339 inline const CoordType & cP1( const int j ) const { return _v[(j+1)%4];}
00340 inline const CoordType & cP2( const int j ) const { return _v[(j+2)%4];}
00341 inline const CoordType & cP3( const int j ) const { return _v[(j+3)%4];}
00342
00344 CoordType ComputeBarycenter()
00345 {
00346 return((_v[0] + _v[1] + _v[2]+ _v[3])/4);
00347 }
00348
00350 double SolidAngle(int vind)
00351 {
00352 double da0=DiedralAngle(EofV(vind,0));
00353 double da1=DiedralAngle(EofV(vind,1));
00354 double da2=DiedralAngle(EofV(vind,2));
00355
00356 return((da0 + da1 + da2)- M_PI);
00357 }
00358
00360 double DiedralAngle(int edgeind)
00361 {
00362 int f1=FofE(edgeind,0);
00363 int f2=FofE(edgeind,1);
00364 CoordType p0=_v[FofV(f1,0)];
00365 CoordType p1=_v[FofV(f1,1)];
00366 CoordType p2=_v[FofV(f1,2)];
00367 CoordType norm1=((p1-p0)^(p2-p0));
00368 p0=_v[FofV(f2,0)];
00369 p1=_v[FofV(f2,1)];
00370 p2=_v[FofV(f2,2)];
00371 CoordType norm2=((p1-p0)^(p2-p0));
00372 norm1.Normalize();
00373 norm2.Normalize();
00374 return (M_PI-acos(double(norm1*norm2)));
00375 }
00376
00378 ScalarType ComputeAspectRatio()
00379 {
00380 double a0=SolidAngle(0);
00381 double a1=SolidAngle(1);
00382 double a2=SolidAngle(2);
00383 double a3=SolidAngle(3);
00384 return (ScalarType)std::min(a0,std::min(a1,std::min(a2,a3)));
00385 }
00386
00388 bool IsInside(const CoordType &p)
00389 {
00390
00391 vcg::Box3<typename CoordType::ScalarType> bb;
00392 for (int i=0;i<4;i++)
00393 bb.Add(_v[i]);
00394
00395 if (!bb.IsIn(p))
00396 return false;
00397
00398 vcg::Matrix44<ScalarType> M0;
00399 vcg::Matrix44<ScalarType> M1;
00400 vcg::Matrix44<ScalarType> M2;
00401 vcg::Matrix44<ScalarType> M3;
00402 vcg::Matrix44<ScalarType> M4;
00403
00404 CoordType p1=_v[0];
00405 CoordType p2=_v[1];
00406 CoordType p3=_v[2];
00407 CoordType p4=_v[3];
00408
00409 M0[0][0]=p1.V(0);
00410 M0[0][1]=p1.V(1);
00411 M0[0][2]=p1.V(2);
00412 M0[1][0]=p2.V(0);
00413 M0[1][1]=p2.V(1);
00414 M0[1][2]=p2.V(2);
00415 M0[2][0]=p3.V(0);
00416 M0[2][1]=p3.V(1);
00417 M0[2][2]=p3.V(2);
00418 M0[3][0]=p4.V(0);
00419 M0[3][1]=p4.V(1);
00420 M0[3][2]=p4.V(2);
00421 M0[0][3]=1;
00422 M0[1][3]=1;
00423 M0[2][3]=1;
00424 M0[3][3]=1;
00425
00426 M1=M0;
00427 M1[0][0]=p.V(0);
00428 M1[0][1]=p.V(1);
00429 M1[0][2]=p.V(2);
00430
00431 M2=M0;
00432 M2[1][0]=p.V(0);
00433 M2[1][1]=p.V(1);
00434 M2[1][2]=p.V(2);
00435
00436 M3=M0;
00437 M3[2][0]=p.V(0);
00438 M3[2][1]=p.V(1);
00439 M3[2][2]=p.V(2);
00440
00441 M4=M0;
00442 M4[3][0]=p.V(0);
00443 M4[3][1]=p.V(1);
00444 M4[3][2]=p.V(2);
00445
00446 ScalarType d0=M0.Determinant();
00447 ScalarType d1=M1.Determinant();
00448 ScalarType d2=M2.Determinant();
00449 ScalarType d3=M3.Determinant();
00450 ScalarType d4=M4.Determinant();
00451
00452
00453 return (((d0>0)&&(d1>0)&&(d2>0)&&(d3>0)&&(d4>0))||((d0<0)&&(d1<0)&&(d2<0)&&(d3<0)&&(d4<0)));
00454 }
00455
00456 void InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &c ,ScalarType &d)
00457 {
00458 const ScalarType EPSILON = ScalarType(0.000001);
00459 Matrix33<ScalarType> M;
00460
00461 CoordType v0=P(0)-P(2);
00462 CoordType v1=P(1)-P(2);
00463 CoordType v2=P(3)-P(2);
00464 CoordType v3=bq-P(2);
00465
00466 M[0][0]=v0.X();
00467 M[1][0]=v0.Y();
00468 M[2][0]=v0.Z();
00469
00470 M[0][1]=v1.X();
00471 M[1][1]=v1.Y();
00472 M[2][1]=v1.Z();
00473
00474 M[0][2]=v2.X();
00475 M[1][2]=v2.Y();
00476 M[2][2]=v2.Z();
00477
00478 Matrix33<ScalarType> inv_M =vcg::Inverse<ScalarType>(M);
00479
00480 CoordType Barycentric=inv_M*v3;
00481
00482 a=Barycentric.V(0);
00483 b=Barycentric.V(1);
00484 d=Barycentric.V(2);
00485 c=1-(a+b+d);
00486
00487 }
00488
00489 };
00490
00491
00492 template<class ScalarType>
00493 Point3<ScalarType> Barycenter(const Tetra3<ScalarType> &t)
00494 {
00495 return ((t.cP(0)+t.cP(1)+t.cP(2)+t.cP(3))/(ScalarType) 4.0);
00496 }
00497
00498
00499 template<class TetraType>
00500 typename TetraType::ScalarType ComputeVolume( const TetraType & t){
00501 return (typename TetraType::ScalarType)((( t.cP(2)-t.cP(0))^(t.cP(1)-t.cP(0) ))*(t.cP(3)-t.cP(0))/6.0);
00502 }
00503
00505 template<class TetraType>
00506 Point3<typename TetraType::ScalarType> Normal( const TetraType &t,const int &face)
00507 {
00508 return(((t.cP(Tetra::VofF(face,1))-t.cP(Tetra::VofF(face,0)))^(t.cP(Tetra::VofF(face,2))-t.cP(Tetra::VofF(face,0)))).Normalize());
00509 }
00511 }
00512
00513
00514 #endif
00515