CRITICAL CHANGE: the commonly used function Normal() used to compute the normal of a triangle has been changed into TriangleNormal()

This commit is contained in:
Paolo Cignoni 2014-11-12 00:04:26 +00:00
parent 3bc278c224
commit 16f4795588
1 changed files with 74 additions and 88 deletions

View File

@ -36,26 +36,26 @@ namespace vcg {
/** \addtogroup space */ /** \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...) 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 ScalarTriangleType> class Triangle3 template <class ScalarTriangleType> class Triangle3
{ {
public: public:
typedef ScalarTriangleType ScalarType; typedef ScalarTriangleType ScalarType;
typedef Point3< ScalarType > CoordType; typedef Point3< ScalarType > CoordType;
/// The bounding box type /// The bounding box type
typedef Box3<ScalarType> BoxType; typedef Box3<ScalarType> BoxType;
/********************************************* /*********************************************
blah blah
blah blah
**/ **/
Triangle3(){} Triangle3(){}
Triangle3(const CoordType & c0,const CoordType & c1,const CoordType & c2){_v[0]=c0;_v[1]=c1;_v[2]=c2;} Triangle3(const CoordType & c0,const CoordType & c1,const CoordType & c2){_v[0]=c0;_v[1]=c1;_v[2]=c2;}
protected: protected:
/// Vector of vertex pointer incident in the face /// Vector of vertex pointer incident in the face
Point3<ScalarType> _v[3]; Point3<ScalarType> _v[3];
public: public:
/// Shortcut per accedere ai punti delle facce /// Shortcut per accedere ai punti delle facce
@ -79,7 +79,7 @@ public:
/// Returns the normal to the plane passing through p0,p1,p2 /// Returns the normal to the plane passing through p0,p1,p2
template<class TriangleType> template<class TriangleType>
Point3<typename TriangleType::ScalarType> Normal(const TriangleType &t) Point3<typename TriangleType::ScalarType> TriangleNormal(const TriangleType &t)
{ {
return (( t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0))); return (( t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0)));
} }
@ -89,20 +89,6 @@ Point3Type Normal( Point3Type const &p0, Point3Type const & p1, Point3Type cons
return (( p1 - p0) ^ (p2 - p0)); return (( p1 - p0) ^ (p2 - p0));
} }
/// Like the above, it returns the normal to the plane passing through p0,p1,p2, but normalized.
template<class TriangleType>
typename TriangleType::CoordType NormalizedNormal(const TriangleType &t)
{
return (( t.cP(1) - t.cP(0)) ^ (t.cP(2) - t.cP(0))).Normalize();
}
template<class Point3Type>
Point3Type NormalizedNormal( Point3Type const &p0, Point3Type const & p1, Point3Type const & p2)
{
return (( p1 - p0) ^ (p2 - p0)).Normalize();
}
/********************** Interpolation **********************/ /********************** Interpolation **********************/
// The function to computing barycentric coords of a point inside a triangle. // The function to computing barycentric coords of a point inside a triangle.
@ -120,41 +106,41 @@ Point3Type NormalizedNormal( Point3Type const &p0, Point3Type const & p1, Point
template<class TriangleType, class ScalarType> template<class TriangleType, class ScalarType>
bool InterpolationParameters(const TriangleType t, const int Axis, const Point3<ScalarType> & P, Point3<ScalarType> & L) bool InterpolationParameters(const TriangleType t, const int Axis, const Point3<ScalarType> & P, Point3<ScalarType> & L)
{ {
typedef Point2<ScalarType> P2; typedef Point2<ScalarType> 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==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==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); 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; return false;
} }
/// Handy Wrapper of the above one that uses the passed normal N to choose the right orientation /// Handy Wrapper of the above one that uses the passed normal N to choose the right orientation
template<class TriangleType, class ScalarType> template<class TriangleType, class ScalarType>
bool InterpolationParameters(const TriangleType t, const Point3<ScalarType> & N, const Point3<ScalarType> & P, Point3<ScalarType> & L) bool InterpolationParameters(const TriangleType t, const Point3<ScalarType> & N, const Point3<ScalarType> & P, Point3<ScalarType> & L)
{ {
if(fabs(N[0])>fabs(N[1])) if(fabs(N[0])>fabs(N[1]))
{ {
if(fabs(N[0])>fabs(N[2])) if(fabs(N[0])>fabs(N[2]))
return InterpolationParameters(t,0,P,L); /* 0 > 1 ? 2 */ return InterpolationParameters(t,0,P,L); /* 0 > 1 ? 2 */
else else
return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */
} }
else else
{ {
if(fabs(N[1])>fabs(N[2])) if(fabs(N[1])>fabs(N[2]))
return InterpolationParameters(t,1,P,L); /* 1 > 0 ? 2 */ return InterpolationParameters(t,1,P,L); /* 1 > 0 ? 2 */
else else
return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */ return InterpolationParameters(t,2,P,L); /* 2 > 1 ? 2 */
} }
} }
// Function that computes the barycentric coords of a 2D triangle. // Function that computes the barycentric coords of a 2D triangle.
template<class ScalarType> template<class ScalarType>
bool InterpolationParameters2(const Point2<ScalarType> &V1, bool InterpolationParameters2(const Point2<ScalarType> &V1,
const Point2<ScalarType> &V2, const Point2<ScalarType> &V2,
const Point2<ScalarType> &V3, const Point2<ScalarType> &V3,
const Point2<ScalarType> &P, Point3<ScalarType> &L) const Point2<ScalarType> &P, Point3<ScalarType> &L)
{ {
vcg::Triangle2<ScalarType> t2=vcg::Triangle2<ScalarType>(V1,V2,V3); vcg::Triangle2<ScalarType> t2=vcg::Triangle2<ScalarType>(V1,V2,V3);
return (t2.InterpolationParameters(P,L.X(),L.Y(),L.Z() )); return (t2.InterpolationParameters(P,L.X(),L.Y(),L.Z() ));
} }
/// Handy Wrapper of the above one that calculate the normal on the triangle /// Handy Wrapper of the above one that calculate the normal on the triangle
@ -175,19 +161,19 @@ bool InterpolationParameters(const TriangleType t, const Point3<ScalarType> & P,
template<class P3ScalarType> template<class P3ScalarType>
P3ScalarType Quality( Point3<P3ScalarType> const &p0, Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2) P3ScalarType Quality( Point3<P3ScalarType> const &p0, Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2)
{ {
Point3<P3ScalarType> d10=p1-p0; Point3<P3ScalarType> d10=p1-p0;
Point3<P3ScalarType> d20=p2-p0; Point3<P3ScalarType> d20=p2-p0;
Point3<P3ScalarType> d12=p1-p2; Point3<P3ScalarType> d12=p1-p2;
Point3<P3ScalarType> x = d10^d20; Point3<P3ScalarType> x = d10^d20;
P3ScalarType a = Norm( x ); P3ScalarType a = Norm( x );
if(a==0) return 0; // Area zero triangles have surely quality==0; if(a==0) return 0; // Area zero triangles have surely quality==0;
P3ScalarType b = SquaredNorm( d10 ); P3ScalarType b = SquaredNorm( d10 );
if(b==0) return 0; // Again: area zero triangles have surely quality==0; if(b==0) return 0; // Again: area zero triangles have surely quality==0;
P3ScalarType t = b; P3ScalarType t = b;
t = SquaredNorm( d20 ); if ( b<t ) b = t; t = SquaredNorm( d20 ); if ( b<t ) b = t;
t = SquaredNorm( d12 ); if ( b<t ) b = t; t = SquaredNorm( d12 ); if ( b<t ) b = t;
return a/b; return a/b;
} }
@ -203,19 +189,19 @@ typename TriangleType::ScalarType QualityFace(const TriangleType &t)
/// e.g. Equilateral triangle 1, halfsquare: 0.81, ... up to a line that has zero quality. /// e.g. Equilateral triangle 1, halfsquare: 0.81, ... up to a line that has zero quality.
template<class P3ScalarType> template<class P3ScalarType>
P3ScalarType QualityRadii(Point3<P3ScalarType> const &p0, P3ScalarType QualityRadii(Point3<P3ScalarType> const &p0,
Point3<P3ScalarType> const &p1, Point3<P3ScalarType> const &p1,
Point3<P3ScalarType> const &p2) { Point3<P3ScalarType> const &p2) {
P3ScalarType a=(p1-p0).Norm(); P3ScalarType a=(p1-p0).Norm();
P3ScalarType b=(p2-p0).Norm(); P3ScalarType b=(p2-p0).Norm();
P3ScalarType c=(p1-p2).Norm(); P3ScalarType c=(p1-p2).Norm();
P3ScalarType sum = (a + b + c)*0.5; P3ScalarType sum = (a + b + c)*0.5;
P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum);
if(area2 <= 0) return 0; if(area2 <= 0) return 0;
//circumradius: (a*b*c)/(4*sqrt(area2)) //circumradius: (a*b*c)/(4*sqrt(area2))
//inradius: (a*b*c)/(4*circumradius*sum) => sqrt(area2)/sum; //inradius: (a*b*c)/(4*circumradius*sum) => sqrt(area2)/sum;
return (8*area2)/(a*b*c*sum); return (8*area2)/(a*b*c*sum);
} }
/// Compute a shape quality measure of the triangle composed by points p0,p1,p2 /// Compute a shape quality measure of the triangle composed by points p0,p1,p2
@ -224,16 +210,16 @@ P3ScalarType QualityRadii(Point3<P3ScalarType> const &p0,
/// the range is range [0, 1] /// the range is range [0, 1]
template<class P3ScalarType> template<class P3ScalarType>
P3ScalarType QualityMeanRatio(Point3<P3ScalarType> const &p0, P3ScalarType QualityMeanRatio(Point3<P3ScalarType> const &p0,
Point3<P3ScalarType> const &p1, Point3<P3ScalarType> const &p1,
Point3<P3ScalarType> const &p2) { Point3<P3ScalarType> const &p2) {
P3ScalarType a=(p1-p0).Norm(); P3ScalarType a=(p1-p0).Norm();
P3ScalarType b=(p2-p0).Norm(); P3ScalarType b=(p2-p0).Norm();
P3ScalarType c=(p1-p2).Norm(); P3ScalarType c=(p1-p2).Norm();
P3ScalarType sum = (a + b + c)*0.5; //semiperimeter P3ScalarType sum = (a + b + c)*0.5; //semiperimeter
P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum); P3ScalarType area2 = sum*(a+b-sum)*(a+c-sum)*(b+c-sum);
if(area2 <= 0) return 0; if(area2 <= 0) return 0;
return (4.0*sqrt(3.0)*sqrt(area2))/(a*a + b*b + c*c); return (4.0*sqrt(3.0)*sqrt(area2))/(a*a + b*b + c*c);
} }