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 #ifndef __VCG_TRIANGLE3
00094 #define __VCG_TRIANGLE3
00095
00096 #include <vcg/space/box3.h>
00097 #include <vcg/space/point2.h>
00098 #include <vcg/space/point3.h>
00099 #include <vcg/space/plane3.h>
00100 #include <vcg/space/segment3.h>
00101
00102 namespace vcg {
00103
00110 template <class ScalarTriangleType> class Triangle3
00111 {
00112 public:
00113 typedef ScalarTriangleType ScalarType;
00114 typedef Point3< ScalarType > CoordType;
00116 typedef Box3<ScalarType> BoxType;
00117
00118
00119
00120
00121
00122 Triangle3(){}
00123 Triangle3(const CoordType & c0,const CoordType & c1,const CoordType & c2){_v[0]=c0;_v[1]=c1;_v[2]=c2;}
00124 protected:
00126 Point3<ScalarType> _v[3];
00127 public:
00128
00130 inline CoordType & P( const int j ) { return _v[j];}
00131 inline CoordType & P0( const int j ) { return _v[j];}
00132 inline CoordType & P1( const int j ) { return _v[(j+1)%3];}
00133 inline CoordType & P2( const int j ) { return _v[(j+2)%3];}
00134 inline const CoordType & P( const int j ) const { return _v[j];}
00135 inline const CoordType & P0( const int j ) const { return _v[j];}
00136 inline const CoordType & P1( const int j ) const { return _v[(j+1)%3];}
00137 inline const CoordType & P2( const int j ) const { return _v[(j+2)%3];}
00138 inline const CoordType & cP0( const int j ) const { return _v[j];}
00139 inline const CoordType & cP1( const int j ) const { return _v[(j+1)%3];}
00140 inline const CoordType & cP2( const int j ) const { return _v[(j+2)%3];}
00141
00142
00143
00144 bool InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &_c ) const{
00145 return InterpolationParameters(*this, bq, a, b,_c );
00146 }
00147
00148
00149
00150
00151
00153 ScalarType QualityFace( ) const
00154 {
00155 return Quality(P(0), P(1), P(2));
00156 }
00157
00158 };
00159
00161 template<class TriangleType>
00162 typename TriangleType::ScalarType QualityFace(const TriangleType &t)
00163 {
00164 return Quality(t.cP(0), t.cP(1), t.cP(2));
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 template<class TriangleType, class ScalarType>
00178 bool InterpolationParameters(const TriangleType t, const int Axis, const Point3<ScalarType> & P, Point3<ScalarType> & L)
00179 {
00180 Point2<ScalarType> test;
00181 typedef Point2<ScalarType> P2;
00182 if(Axis==0) return InterpolationParameters2( P2(t.P(0)[1],t.P(0)[2]), P2(t.P(1)[1],t.P(1)[2]), P2(t.P(2)[1],t.P(2)[2]), P2(P[1],P[2]), L);
00183 if(Axis==1) return InterpolationParameters2( P2(t.P(0)[0],t.P(0)[2]), P2(t.P(1)[0],t.P(1)[2]), P2(t.P(2)[0],t.P(2)[2]), P2(P[0],P[2]), L);
00184 if(Axis==2) return InterpolationParameters2( P2(t.P(0)[0],t.P(0)[1]), P2(t.P(1)[0],t.P(1)[1]), P2(t.P(2)[0],t.P(2)[1]), P2(P[0],P[1]), L);
00185 return false;
00186 }
00188 template<class TriangleType, class ScalarType>
00189 bool InterpolationParameters(const TriangleType t, const Point3<ScalarType> & N, const Point3<ScalarType> & P, Point3<ScalarType> & L)
00190 {
00191 if(N[0]>N[1])
00192 {
00193 if(N[0]>N[2])
00194 return InterpolationParameters(t,0,P,L);
00195 else
00196 return InterpolationParameters(t,2,P,L);
00197 }
00198 else
00199 {
00200 if(N[1]>N[2])
00201 return InterpolationParameters(t,1,P,L);
00202 else
00203 return InterpolationParameters(t,2,P,L);
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212 template<class ScalarType>
00213 bool InterpolationParameters2(const Point2<ScalarType> &V1,
00214 const Point2<ScalarType> &V2,
00215 const Point2<ScalarType> &V3,
00216 const Point2<ScalarType> &P, Point3<ScalarType> &L)
00217 {
00218 ScalarType T00 = V1[0]-V3[0]; ScalarType T01 = V2[0]-V3[0];
00219 ScalarType T10 = V1[1]-V3[1]; ScalarType T11 = V2[1]-V3[1];
00220 ScalarType Det = T00 * T11 - T01*T10;
00221 if(fabs(Det) < 0.0000001)
00222 return false;
00223
00224 ScalarType IT00 = T11/Det; ScalarType IT01 = -T01/Det;
00225 ScalarType IT10 = -T10/Det; ScalarType IT11 = T00/Det;
00226
00227 Point2<ScalarType> Delta = P-V3;
00228
00229 L[0] = IT00*Delta[0] + IT01*Delta[1];
00230 L[1] = IT10*Delta[0] + IT11*Delta[1];
00231
00232 if(L[0]<0) L[0]=0;
00233 if(L[1]<0) L[1]=0;
00234 if(L[0]>1.) L[0]=1;
00235 if(L[1]>1.) L[1]=1;
00236
00237 L[2] = 1. - L[1] - L[0];
00238 if(L[2]<0) L[2]=0;
00239
00240 assert(L[2] >= -0.00001);
00241
00242 return true;
00243 }
00244
00245
00253 template<class TriangleType, class ScalarType>
00254 bool InterpolationParameters(const TriangleType t,const Point3<ScalarType> & N,const Point3<ScalarType> & bq, ScalarType &a, ScalarType &b, ScalarType &c )
00255 {
00256 Point3<ScalarType> bary;
00257 bool done= InterpolationParameters(t,N,bq,bary);
00258 a=bary[0];
00259 b=bary[1];
00260 c=bary[2];
00261 return done;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 }
00352
00353
00358 template<class P3ScalarType>
00359 P3ScalarType Quality( Point3<P3ScalarType> const &p0, Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2)
00360 {
00361 Point3<P3ScalarType> d10=p1-p0;
00362 Point3<P3ScalarType> d20=p2-p0;
00363 Point3<P3ScalarType> d12=p1-p2;
00364 Point3<P3ScalarType> x = d10^d20;
00365
00366 P3ScalarType a = Norm( x );
00367 if(a==0) return 0;
00368 P3ScalarType b = SquaredNorm( d10 );
00369 P3ScalarType t = b;
00370 t = SquaredNorm( d20 ); if ( b<t ) b = t;
00371 t = SquaredNorm( d12 ); if ( b<t ) b = t;
00372 assert(b!=0.0);
00373 return a/b;
00374 }
00375
00376
00381 template<class P3ScalarType>
00382 P3ScalarType QualityRadii(Point3<P3ScalarType> const &p0,
00383 Point3<P3ScalarType> const &p1,
00384 Point3<P3ScalarType> const &p2) {
00385
00386 P3ScalarType a=(p1-p0).Norm();
00387 P3ScalarType b=(p2-p0).Norm();
00388 P3ScalarType c=(p1-p2).Norm();
00389
00390 P3ScalarType sum = (a + b + c)*0.5;
00391 P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum);
00392 if(area2 <= 0) return 0;
00393
00394
00395 return (8*area2)/(a*b*c*sum);
00396 }
00397
00402 template<class P3ScalarType>
00403 P3ScalarType QualityMeanRatio(Point3<P3ScalarType> const &p0,
00404 Point3<P3ScalarType> const &p1,
00405 Point3<P3ScalarType> const &p2) {
00406
00407 P3ScalarType a=(p1-p0).Norm();
00408 P3ScalarType b=(p2-p0).Norm();
00409 P3ScalarType c=(p1-p2).Norm();
00410 P3ScalarType sum = (a + b + c)*0.5;
00411 P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum);
00412 if(area2 <= 0) return 0;
00413 return (4.0*sqrt(3.0)*sqrt(area2))/(a*a + b*b + c*c);
00414 }
00415
00417 template<class TriangleType>
00418 Point3<typename TriangleType::ScalarType> Normal(const TriangleType &t)
00419 {
00420 return (( t.P(1) - t.P(0)) ^ (t.P(2) - t.P(0)));
00421 }
00422 template<class Point3Type>
00423 Point3Type Normal( Point3Type const &p0, Point3Type const & p1, Point3Type const & p2)
00424 {
00425 return (( p1 - p0) ^ (p2 - p0));
00426 }
00427
00428
00430 template<class TriangleType>
00431 Point3<typename TriangleType::ScalarType> NormalizedNormal(const TriangleType &t)
00432 {
00433 return (( t.P(1) - t.P(0)) ^ (t.P(2) - t.P(0))).Normalize();
00434 }
00435 template<class Point3Type>
00436 Point3Type NormalizedNormal( Point3Type const &p0, Point3Type const & p1, Point3Type const & p2)
00437 {
00438 return (( p1 - p0) ^ (p2 - p0)).Normalize();
00439 }
00440
00441
00442
00444
00445
00446
00447
00448
00449
00450 template<class TriangleType>
00451 typename TriangleType::ScalarType DoubleArea(const TriangleType &t)
00452 {
00453 return Norm( (t.P(1) - t.P(0)) ^ (t.P(2) - t.P(0)) );
00454 }
00455
00456 template<class TriangleType>
00457 typename TriangleType::ScalarType CosWedge(const TriangleType &t, int k)
00458 {
00459 typename TriangleType::CoordType
00460 e0 = t.P((k+1)%3) - t.P(k),
00461 e1 = t.P((k+2)%3) - t.P(k);
00462 return (e0*e1)/(e0.Norm()*e1.Norm());
00463 }
00464
00465 template<class TriangleType>
00466 Point3<typename TriangleType::ScalarType> Barycenter(const TriangleType &t)
00467 {
00468 return ((t.P(0)+t.P(1)+t.P(2))/(typename TriangleType::ScalarType) 3.0);
00469 }
00470
00471 template<class TriangleType>
00472 typename TriangleType::ScalarType Perimeter(const TriangleType &t)
00473 {
00474 return Distance(t.P(0),t.P(1))+
00475 Distance(t.P(1),t.P(2))+
00476 Distance(t.P(2),t.P(0));
00477 }
00478
00479 template<class TriangleType>
00480 Point3<typename TriangleType::ScalarType> Circumcenter(const TriangleType &t)
00481 {
00482 typename TriangleType::ScalarType a2 = (t.P(1) - t.P(2)).SquaredNorm();
00483 typename TriangleType::ScalarType b2 = (t.P(2) - t.P(0)).SquaredNorm();
00484 typename TriangleType::ScalarType c2 = (t.P(0) - t.P(1)).SquaredNorm();
00485 Point3<typename TriangleType::ScalarType>c = t.P(0)*a2*(-a2 + b2 + c2) +
00486 t.P(1)*b2*( a2 - b2 + c2) +
00487 t.P(2)*c2*( a2 + b2 - c2);
00488 c /= 2*(a2*b2 + a2*c2 + b2*c2) - a2*a2 - b2*b2 - c2*c2;
00489 return c;
00490 }
00491
00501 template<class TriangleType>
00502 void TrianglePointDistance(const TriangleType &t,
00503 const typename TriangleType::CoordType & q,
00504 typename TriangleType::ScalarType & dist,
00505 typename TriangleType::CoordType & closest )
00506 {
00507 typedef typename TriangleType::CoordType CoordType;
00508 typedef typename TriangleType::ScalarType ScalarType;
00509
00510 CoordType clos[3];
00511 ScalarType distv[3];
00512 CoordType clos_proj;
00513 ScalarType distproj;
00514
00516 vcg::Plane3<ScalarType> plane;
00517 plane.Init(t.P(0),t.P(1),t.P(2));
00518 clos_proj=plane.Projection(q);
00519
00521 CoordType n=(t.P(1)-t.P(0))^(t.P(2)-t.P(0));
00522 CoordType n0=(t.P(0)-clos_proj)^(t.P(1)-clos_proj);
00523 CoordType n1=(t.P(1)-clos_proj)^(t.P(2)-clos_proj);
00524 CoordType n2=(t.P(2)-clos_proj)^(t.P(0)-clos_proj);
00525 distproj=(clos_proj-q).Norm();
00526 if (((n*n0)>=0)&&((n*n1)>=0)&&((n*n2)>=0))
00527 {
00528 closest=clos_proj;
00529 dist=distproj;
00530 return;
00531 }
00532
00533
00534
00535 vcg::Segment3<ScalarType> e0=vcg::Segment3<ScalarType>(t.P(0),t.P(1));
00536 vcg::Segment3<ScalarType> e1=vcg::Segment3<ScalarType>(t.P(1),t.P(2));
00537 vcg::Segment3<ScalarType> e2=vcg::Segment3<ScalarType>(t.P(2),t.P(0));
00538 clos[0]=ClosestPoint<ScalarType>( e0, q);
00539 clos[1]=ClosestPoint<ScalarType>( e1, q);
00540 clos[2]=ClosestPoint<ScalarType>( e2, q);
00541
00542 distv[0]=(clos[0]-q).Norm();
00543 distv[1]=(clos[1]-q).Norm();
00544 distv[2]=(clos[2]-q).Norm();
00545 int min=0;
00546
00548 for (int i=1;i<3;i++)
00549 {
00550 if (distv[i]<distv[min])
00551 min=i;
00552 }
00553
00554 closest=clos[min];
00555 dist=distv[min];
00556 }
00557
00558
00559 }
00560
00561
00562 #endif
00563