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 namespace vcg {
00136 class Tetra
00137 {
00138 public:
00139
00140
00141
00142
00143 static int VofE(const int &indexE,const int &indexV)
00144 { assert ((indexE<6)&&(indexV<2));
00145 static int edgevert[6][2] ={{0,1},
00146 {0,2},
00147 {0,3},
00148 {1,2},
00149 {1,3},
00150 {2,3}};
00151 return (edgevert[indexE][indexV]);
00152 }
00153
00154 static int VofF(const int &indexF,const int &indexV)
00155 { assert ((indexF<4)&&(indexV<3));
00156 static int facevert[4][3]={{0,1,2},
00157 {0,3,1},
00158 {0,2,3},
00159 {1,3,2}};
00160 return (facevert[indexF][indexV]);
00161 }
00162
00163 static int EofV(const int &indexV,const int &indexE)
00164 {
00165 assert ((indexE<3)&&(indexV<4));
00166 static int vertedge[4][3]={{0,1,2},
00167 {0,3,4},
00168 {5,1,3},
00169 {4,5,2}};
00170 return vertedge[indexV][indexE];
00171 }
00172
00173 static int EofF(const int &indexF,const int &indexE)
00174 { assert ((indexF<4)&&(indexE<3));
00175 static int faceedge[4][3]={{0,3,1},
00176 {2,4,0},
00177 {1,5,2},
00178 {4,5,3}
00179 };
00180 return faceedge [indexF][indexE];
00181 }
00182
00183 static int FofV(const int &indexV,const int &indexF)
00184 {
00185 assert ((indexV<4)&&(indexF<3));
00186 static int vertface[4][3]={{0,1,2},
00187 {0,3,1},
00188 {0,2,3},
00189 {1,3,2}};
00190 return vertface[indexV][indexF];
00191 }
00192
00193 static int FofE(const int &indexE,const int &indexSide)
00194 { assert ((indexE<6)&&(indexSide<2));
00195 static int edgeface[6][2]={{0,1},
00196 {0,2},
00197 {1,2},
00198 {0,3},
00199 {1,3},
00200 {2,3}};
00201 return edgeface [indexE][indexSide];
00202 }
00203
00204 static int VofEE(const int &indexE0,const int &indexE1)
00205 {
00206 assert ((indexE0<6)&&(indexE0>=0));
00207 assert ((indexE1<6)&&(indexE1>=0));
00208 static int edgesvert[6][6]={{-1,0,0,1,1,-1},
00209 {0,-1,0,2,-1,2},
00210 {0,0,-1,-1,3,3},
00211 {1,2,-1,-1,1,2},
00212 {1,-1,3,1,-1,3},
00213 {-1,2,3,2,3,-1}};
00214 return (edgesvert[indexE0][indexE1]);
00215 }
00216
00217 static int VofFFF(const int &indexF0,const int &indexF1,const int &indexF2)
00218 {
00219 assert ((indexF0<4)&&(indexF0>=0));
00220 assert ((indexF1<4)&&(indexF1>=0));
00221 assert ((indexF2<4)&&(indexF2>=0));
00222 static int facesvert[4][4][4]={
00223 {
00224 {-1,-1,-1,-1},{-1,-1,0,1},{-1,0,-1,2},{-1,1,2,-1}
00225 },
00226 {
00227 {-1,-1,0,1},{-1,-1,-1,-1},{0,-1,-1,3},{1,-1,3,-1}
00228 },
00229 {
00230 {-1,0,-1,2},{0,-1,-1,3},{-1,-1,-1,-1},{2,3,-1,-1}
00231 },
00232 {
00233 {-1,1,2,-1},{1,-1,3,-1},{2,3,-1,-1},{-1,-1,-1,-1}
00234 }
00235 };
00236 return facesvert[indexF0][indexF1][indexF2];
00237 }
00238
00239 static int EofFF(const int &indexF0,const int &indexF1)
00240 {
00241 assert ((indexF0<4)&&(indexF0>=0));
00242 assert ((indexF1<4)&&(indexF1>=0));
00243 static int facesedge[4][4]={{-1, 0, 1, 3},
00244 { 0, -1, 2, 4},
00245 { 1, 2, -1, 5},
00246 { 3, 4, 5, -1}};
00247 return (facesedge[indexF0][indexF1]);
00248 }
00249
00250 static int EofVV(const int &indexV0,const int &indexV1)
00251 {
00252 assert ((indexV0<4)&&(indexV0>=0));
00253 assert ((indexV1<4)&&(indexV1>=0));
00254 static int verticesedge[4][4]={{-1, 0, 1, 2},
00255 { 0, -1, 3, 4},
00256 { 1, 3, -1, 5},
00257 { 2, 4, 5, -1}};
00258
00259 return verticesedge[indexV0][indexV1];
00260 }
00261
00262 static int FofVVV(const int &indexV0,const int &indexV1,const int &indexV2)
00263 {
00264
00265 assert ((indexV0<4)&&(indexV0>=0));
00266 assert ((indexV1<4)&&(indexV1>=0));
00267 assert ((indexV2<4)&&(indexV2>=0));
00268
00269 static int verticesface[4][4][4]={
00270 {
00271 {-1,-1,-1,-1},{-1,-1,0,1},{-1,0,-1,2},{-1,1,2,-1}
00272 },
00273 {
00274 {-1,-1,0,1},{-1,-1,-1,-1},{0,-1,-1,3},{1,-1,3,-1}
00275 },
00276 {
00277 {-1,0,-1,2},{0,-1,-1,3},{-1,-1,-1,-1},{2,3,-1,-1}
00278 },
00279 {
00280 {-1,1,2,-1},{1,-1,3,-1},{2,3,-1,-1},{-1,-1,-1,-1}
00281 }
00282 };
00283 return verticesface[indexV0][indexV1][indexV2];
00284 }
00285
00286 static int FofEE(const int &indexE0,const int &indexE1)
00287 {
00288 assert ((indexE0<6)&&(indexE0>=0));
00289 assert ((indexE1<6)&&(indexE1>=0));
00290 static int edgesface[6][6]={{-1,0,1,0,1,-1},
00291 {0,-1,2,0,-1,2},
00292 {1,2,-1,-1,1,2},
00293 {0,0,-1,-1,3,3},
00294 {1,-1,1,3,-1,3},
00295 {-1,2,2,3,3,-1}};
00296
00297 return edgesface[indexE0][indexE1];
00298 }
00299 };
00300
00305 template <class ScalarType>
00306 class Tetra3:public Tetra
00307 {
00308 public:
00309 typedef Point3< ScalarType > CoordType;
00310
00311
00312
00313
00314
00315
00316 private:
00318 CoordType _v[4];
00319
00320 public:
00321
00323 inline CoordType & P( const int j ) { return _v[j];}
00324 inline CoordType const & cP( const int j )const { return _v[j];}
00325
00326 inline CoordType & P0( const int j ) { return _v[j];}
00327 inline CoordType & P1( const int j ) { return _v[(j+1)%4];}
00328 inline CoordType & P2( const int j ) { return _v[(j+2)%4];}
00329 inline CoordType & P3( const int j ) { return _v[(j+3)%4];}
00330
00331 inline const CoordType & P0( const int j ) const { return _v[j];}
00332 inline const CoordType & P1( const int j ) const { return _v[(j+1)%4];}
00333 inline const CoordType & P2( const int j ) const { return _v[(j+2)%4];}
00334 inline const CoordType & P3( const int j ) const { return _v[(j+3)%4];}
00335
00336 inline const CoordType & cP0( const int j ) const { return _v[j];}
00337 inline const CoordType & cP1( const int j ) const { return _v[(j+1)%4];}
00338 inline const CoordType & cP2( const int j ) const { return _v[(j+2)%4];}
00339 inline const CoordType & cP3( const int j ) const { return _v[(j+3)%4];}
00340
00342 CoordType ComputeBarycenter()
00343 {
00344 return((_v[0] + _v[1] + _v[2]+ _v[3])/4);
00345 }
00346
00348 double SolidAngle(int vind)
00349 {
00350 double da0=DiedralAngle(EofV(vind,0));
00351 double da1=DiedralAngle(EofV(vind,1));
00352 double da2=DiedralAngle(EofV(vind,2));
00353
00354 return((da0 + da1 + da2)- M_PI);
00355 }
00356
00358 double DiedralAngle(int edgeind)
00359 {
00360 int f1=FofE(edgeind,0);
00361 int f2=FofE(edgeind,1);
00362 CoordType p0=_v[FofV(f1,0)];
00363 CoordType p1=_v[FofV(f1,1)];
00364 CoordType p2=_v[FofV(f1,2)];
00365 CoordType norm1=((p1-p0)^(p2-p0));
00366 p0=_v[FofV(f2,0)];
00367 p1=_v[FofV(f2,1)];
00368 p2=_v[FofV(f2,2)];
00369 CoordType norm2=((p1-p0)^(p2-p0));
00370 norm1.Normalize();
00371 norm2.Normalize();
00372 return (M_PI-acos(double(norm1*norm2)));
00373 }
00374
00376 ScalarType ComputeAspectRatio()
00377 {
00378 double a0=SolidAngle(0);
00379 double a1=SolidAngle(1);
00380 double a2=SolidAngle(2);
00381 double a3=SolidAngle(3);
00382 return (ScalarType)math::Min(a0,math::Min(a1,math::Min(a2,a3)));
00383 }
00384
00386 bool IsInside(const CoordType &p)
00387 {
00388
00389 vcg::Box3<typename CoordType::ScalarType> bb;
00390 for (int i=0;i<4;i++)
00391 bb.Add(_v[i]);
00392
00393 if (!bb.IsIn(p))
00394 return false;
00395
00396 vcg::Matrix44<ScalarType> M0;
00397 vcg::Matrix44<ScalarType> M1;
00398 vcg::Matrix44<ScalarType> M2;
00399 vcg::Matrix44<ScalarType> M3;
00400 vcg::Matrix44<ScalarType> M4;
00401
00402 CoordType p1=_v[0];
00403 CoordType p2=_v[1];
00404 CoordType p3=_v[2];
00405 CoordType p4=_v[3];
00406
00407 M0[0][0]=p1.V(0);
00408 M0[0][1]=p1.V(1);
00409 M0[0][2]=p1.V(2);
00410 M0[1][0]=p2.V(0);
00411 M0[1][1]=p2.V(1);
00412 M0[1][2]=p2.V(2);
00413 M0[2][0]=p3.V(0);
00414 M0[2][1]=p3.V(1);
00415 M0[2][2]=p3.V(2);
00416 M0[3][0]=p4.V(0);
00417 M0[3][1]=p4.V(1);
00418 M0[3][2]=p4.V(2);
00419 M0[0][3]=1;
00420 M0[1][3]=1;
00421 M0[2][3]=1;
00422 M0[3][3]=1;
00423
00424 M1=M0;
00425 M1[0][0]=p.V(0);
00426 M1[0][1]=p.V(1);
00427 M1[0][2]=p.V(2);
00428
00429 M2=M0;
00430 M2[1][0]=p.V(0);
00431 M2[1][1]=p.V(1);
00432 M2[1][2]=p.V(2);
00433
00434 M3=M0;
00435 M3[2][0]=p.V(0);
00436 M3[2][1]=p.V(1);
00437 M3[2][2]=p.V(2);
00438
00439 M4=M0;
00440 M4[3][0]=p.V(0);
00441 M4[3][1]=p.V(1);
00442 M4[3][2]=p.V(2);
00443
00444 ScalarType d0=M0.Determinant();
00445 ScalarType d1=M1.Determinant();
00446 ScalarType d2=M2.Determinant();
00447 ScalarType d3=M3.Determinant();
00448 ScalarType d4=M4.Determinant();
00449
00450
00451 return (((d0>0)&&(d1>0)&&(d2>0)&&(d3>0)&&(d4>0))||((d0<0)&&(d1<0)&&(d2<0)&&(d3<0)&&(d4<0)));
00452 }
00453
00454 void InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &c ,ScalarType &d)
00455 {
00456 const ScalarType EPSILON = ScalarType(0.000001);
00457 Matrix33<ScalarType> M;
00458
00459 CoordType v0=P(0)-P(2);
00460 CoordType v1=P(1)-P(2);
00461 CoordType v2=P(3)-P(2);
00462 CoordType v3=bq-P(2);
00463
00464 M[0][0]=v0.X();
00465 M[1][0]=v0.Y();
00466 M[2][0]=v0.Z();
00467
00468 M[0][1]=v1.X();
00469 M[1][1]=v1.Y();
00470 M[2][1]=v1.Z();
00471
00472 M[0][2]=v2.X();
00473 M[1][2]=v2.Y();
00474 M[2][2]=v2.Z();
00475
00476 Matrix33<ScalarType> inv_M =vcg::Inverse<ScalarType>(M);
00477
00478 CoordType Barycentric=inv_M*v3;
00479
00480 a=Barycentric.V(0);
00481 b=Barycentric.V(1);
00482 c=Barycentric.V(2);
00483 d=1-(a+b+c);
00484
00485 }
00486
00487 };
00488
00489
00490 template<class ScalarType>
00491 Point3<ScalarType> Barycenter(const Tetra3<ScalarType> &t)
00492 {
00493 return ((t.cP(0)+t.cP(1)+t.cP(2)+t.cP(3))/(ScalarType) 4.0);
00494 }
00495
00496
00497 template<class TetraType>
00498 typename TetraType::ScalarType ComputeVolume( const TetraType & t){
00499 return (typename TetraType::ScalarType)((( t.cP(2)-t.cP(0))^(t.cP(1)-t.cP(0) ))*(t.cP(3)-t.cP(0))/6.0);
00500 }
00501
00503 template<class TetraType>
00504 Point3<typename TetraType::ScalarType> Normal( const TetraType &t,const int &face)
00505 {
00506 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());
00507 }
00509 }
00510
00511
00512 #endif
00513