diff --git a/vcg/space/triangle3.h b/vcg/space/triangle3.h index 9b5bbcc6..541c69ab 100644 --- a/vcg/space/triangle3.h +++ b/vcg/space/triangle3.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -35,27 +35,27 @@ namespace vcg { /** \addtogroup space */ /*@{*/ -/** - Templated class for storing a generic triangle in a 3D space. +/** + Templated class for storing a generic triangle in a 3D space. Note the relation with the Face class of TriMesh complex, both classes provide the P(i) access functions to their points and therefore they share the algorithms on it (e.g. area, normal etc...) */ template class Triangle3 { public: typedef ScalarTriangleType ScalarType; - typedef Point3< ScalarType > CoordType; - /// The bounding box type - typedef Box3 BoxType; + typedef Point3< ScalarType > CoordType; + /// The bounding box type + typedef Box3 BoxType; /********************************************* blah blah **/ - Triangle3(){} - Triangle3(const CoordType & c0,const CoordType & c1,const CoordType & c2){_v[0]=c0;_v[1]=c1;_v[2]=c2;} + Triangle3(){} + Triangle3(const CoordType & c0,const CoordType & c1,const CoordType & c2){_v[0]=c0;_v[1]=c1;_v[2]=c2;} protected: - /// Vector of vertex pointer incident in the face - Point3 _v[3]; + /// Vector of vertex pointer incident in the face + Point3 _v[3]; public: /// Shortcut per accedere ai punti delle facce @@ -79,7 +79,7 @@ public: /// Returns the normal to the plane passing through p0,p1,p2 template -Point3 Normal(const TriangleType &t) +Point3 TriangleNormal(const TriangleType &t) { return (( t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0))); } @@ -89,24 +89,10 @@ Point3Type Normal( Point3Type const &p0, Point3Type const & p1, Point3Type cons return (( p1 - p0) ^ (p2 - p0)); } -/// Like the above, it returns the normal to the plane passing through p0,p1,p2, but normalized. -template -typename TriangleType::CoordType NormalizedNormal(const TriangleType &t) -{ - return (( t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0))).Normalize(); -} -template -Point3Type NormalizedNormal( Point3Type const &p0, Point3Type const & p1, Point3Type const & p2) -{ - return (( p1 - p0) ^ (p2 - p0)).Normalize(); -} - - - /********************** Interpolation **********************/ // The function to computing barycentric coords of a point inside a triangle. -// it requires the knowledge of what is the direction that is more orthogonal to the face plane. +// it requires the knowledge of what is the direction that is more orthogonal to the face plane. // ScalarType nx = math::Abs((*fi).cN()[0]); // ScalarType ny = math::Abs((*fi).cN()[1]); // ScalarType nz = math::Abs((*fi).cN()[2]); @@ -120,41 +106,41 @@ Point3Type NormalizedNormal( Point3Type const &p0, Point3Type const & p1, Point template bool InterpolationParameters(const TriangleType t, const int Axis, const Point3 & P, Point3 & L) { - typedef Point2 P2; - if(Axis==0) return InterpolationParameters2( P2(t.cP(0)[1],t.cP(0)[2]), P2(t.cP(1)[1],t.cP(1)[2]), P2(t.cP(2)[1],t.cP(2)[2]), P2(P[1],P[2]), L); - if(Axis==1) return InterpolationParameters2( P2(t.cP(0)[0],t.cP(0)[2]), P2(t.cP(1)[0],t.cP(1)[2]), P2(t.cP(2)[0],t.cP(2)[2]), P2(P[0],P[2]), L); - if(Axis==2) return InterpolationParameters2( P2(t.cP(0)[0],t.cP(0)[1]), P2(t.cP(1)[0],t.cP(1)[1]), P2(t.cP(2)[0],t.cP(2)[1]), P2(P[0],P[1]), L); - return false; + typedef Point2 P2; + if(Axis==0) return InterpolationParameters2( P2(t.cP(0)[1],t.cP(0)[2]), P2(t.cP(1)[1],t.cP(1)[2]), P2(t.cP(2)[1],t.cP(2)[2]), P2(P[1],P[2]), L); + if(Axis==1) return InterpolationParameters2( P2(t.cP(0)[0],t.cP(0)[2]), P2(t.cP(1)[0],t.cP(1)[2]), P2(t.cP(2)[0],t.cP(2)[2]), P2(P[0],P[2]), L); + if(Axis==2) return InterpolationParameters2( P2(t.cP(0)[0],t.cP(0)[1]), P2(t.cP(1)[0],t.cP(1)[1]), P2(t.cP(2)[0],t.cP(2)[1]), P2(P[0],P[1]), L); + return false; } /// Handy Wrapper of the above one that uses the passed normal N to choose the right orientation template bool InterpolationParameters(const TriangleType t, const Point3 & N, const Point3 & P, Point3 & L) { if(fabs(N[0])>fabs(N[1])) - { + { if(fabs(N[0])>fabs(N[2])) - return InterpolationParameters(t,0,P,L); /* 0 > 1 ? 2 */ - else - return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ - } - else - { + return InterpolationParameters(t,0,P,L); /* 0 > 1 ? 2 */ + else + return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ + } + else + { if(fabs(N[1])>fabs(N[2])) - return InterpolationParameters(t,1,P,L); /* 1 > 0 ? 2 */ - else - return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ - } + return InterpolationParameters(t,1,P,L); /* 1 > 0 ? 2 */ + else + return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ + } } // Function that computes the barycentric coords of a 2D triangle. template bool InterpolationParameters2(const Point2 &V1, - const Point2 &V2, - const Point2 &V3, - const Point2 &P, Point3 &L) + const Point2 &V2, + const Point2 &V3, + const Point2 &P, Point3 &L) { - vcg::Triangle2 t2=vcg::Triangle2(V1,V2,V3); - return (t2.InterpolationParameters(P,L.X(),L.Y(),L.Z() )); + vcg::Triangle2 t2=vcg::Triangle2(V1,V2,V3); + return (t2.InterpolationParameters(P,L.X(),L.Y(),L.Z() )); } /// Handy Wrapper of the above one that calculate the normal on the triangle @@ -169,25 +155,25 @@ bool InterpolationParameters(const TriangleType t, const Point3 & P, /********************** Quality **********************/ /// Compute a shape quality measure of the triangle composed by points p0,p1,p2 -/// It Returns 2*AreaTri/(MaxEdge^2), -/// the range is range [0.0, 0.866] +/// It Returns 2*AreaTri/(MaxEdge^2), +/// the range is range [0.0, 0.866] /// e.g. Equilateral triangle sqrt(3)/2, halfsquare: 1/2, ... up to a line that has zero quality. template P3ScalarType Quality( Point3 const &p0, Point3 const & p1, Point3 const & p2) { - Point3 d10=p1-p0; - Point3 d20=p2-p0; - Point3 d12=p1-p2; - Point3 x = d10^d20; + Point3 d10=p1-p0; + Point3 d20=p2-p0; + Point3 d12=p1-p2; + Point3 x = d10^d20; - P3ScalarType a = Norm( x ); - if(a==0) return 0; // Area zero triangles have surely quality==0; - P3ScalarType b = SquaredNorm( d10 ); + P3ScalarType a = Norm( x ); + if(a==0) return 0; // Area zero triangles have surely quality==0; + P3ScalarType b = SquaredNorm( d10 ); if(b==0) return 0; // Again: area zero triangles have surely quality==0; - P3ScalarType t = b; - t = SquaredNorm( d20 ); if ( b P3ScalarType QualityRadii(Point3 const &p0, - Point3 const &p1, - Point3 const &p2) { + Point3 const &p1, + Point3 const &p2) { - P3ScalarType a=(p1-p0).Norm(); - P3ScalarType b=(p2-p0).Norm(); - P3ScalarType c=(p1-p2).Norm(); + P3ScalarType a=(p1-p0).Norm(); + P3ScalarType b=(p2-p0).Norm(); + P3ScalarType c=(p1-p2).Norm(); - P3ScalarType sum = (a + b + c)*0.5; - P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); - if(area2 <= 0) return 0; - //circumradius: (a*b*c)/(4*sqrt(area2)) - //inradius: (a*b*c)/(4*circumradius*sum) => sqrt(area2)/sum; - return (8*area2)/(a*b*c*sum); + P3ScalarType sum = (a + b + c)*0.5; + P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); + if(area2 <= 0) return 0; + //circumradius: (a*b*c)/(4*sqrt(area2)) + //inradius: (a*b*c)/(4*circumradius*sum) => sqrt(area2)/sum; + return (8*area2)/(a*b*c*sum); } /// Compute a shape quality measure of the triangle composed by points p0,p1,p2 /// It Returns mean ratio 2sqrt(a, b)/(a+b) where a+b are the eigenvalues of the M^tM of the /// transformation matrix into a regular simplex -/// the range is range [0, 1] +/// the range is range [0, 1] template P3ScalarType QualityMeanRatio(Point3 const &p0, - Point3 const &p1, - Point3 const &p2) { + Point3 const &p1, + Point3 const &p2) { - P3ScalarType a=(p1-p0).Norm(); - P3ScalarType b=(p2-p0).Norm(); - P3ScalarType c=(p1-p2).Norm(); - P3ScalarType sum = (a + b + c)*0.5; //semiperimeter - P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); - if(area2 <= 0) return 0; - return (4.0*sqrt(3.0)*sqrt(area2))/(a*a + b*b + c*c); + P3ScalarType a=(p1-p0).Norm(); + P3ScalarType b=(p2-p0).Norm(); + P3ScalarType c=(p1-p2).Norm(); + P3ScalarType sum = (a + b + c)*0.5; //semiperimeter + P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); + if(area2 <= 0) return 0; + return (4.0*sqrt(3.0)*sqrt(area2))/(a*a + b*b + c*c); } /// Return the Double of area of the triangle -// NOTE the old Area function has been removed to intentionally +// NOTE the old Area function has been removed to intentionally // cause compiling error that will help people to check their code... -// A some people used Area assuming that it returns the double and some not. +// A some people used Area assuming that it returns the double and some not. // So please check your codes!!! // And please DO NOT Insert any Area named function here! template -typename TriangleType::ScalarType DoubleArea(const TriangleType &t) +typename TriangleType::ScalarType DoubleArea(const TriangleType &t) { return Norm( (t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0)) ); } @@ -254,20 +240,20 @@ typename TriangleType::ScalarType DoubleArea(const TriangleType &t) template typename TriangleType::ScalarType CosWedge(const TriangleType &t, int k) { - typename TriangleType::CoordType + typename TriangleType::CoordType e0 = t.cP((k+1)%3) - t.cP(k), e1 = t.cP((k+2)%3) - t.cP(k); return (e0*e1)/(e0.Norm()*e1.Norm()); } template -Point3 Barycenter(const TriangleType &t) +Point3 Barycenter(const TriangleType &t) { return ((t.cP(0)+t.cP(1)+t.cP(2))/(typename TriangleType::ScalarType) 3.0); } template -typename TriangleType::ScalarType Perimeter(const TriangleType &t) +typename TriangleType::ScalarType Perimeter(const TriangleType &t) { return Distance(t.cP(0),t.cP(1))+ Distance(t.cP(1),t.cP(2))+