• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Tri.h

Go to the documentation of this file.
00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum
00002 // Distributed under the GNU Lesser General Public License 2.1 with an
00003 // addendum covering inlined code. (See accompanying files LICENSE and
00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt)
00005 
00006 #ifndef _GMTL_TRI_H_
00007 #define _GMTL_TRI_H_
00008 
00009 #include <gmtl/Point.h>
00010 #include <gmtl/Vec.h>
00011 #include <gmtl/VecOps.h>
00012  
00013 namespace gmtl
00014 {
00022 template< class DATA_TYPE >
00023 class  Tri
00024 {
00025 public:
00029    Tri() {}
00030 
00041    Tri( const Point<DATA_TYPE, 3>& p1, const Point<DATA_TYPE, 3>& p2,
00042         const Point<DATA_TYPE, 3>& p3)
00043    {
00044       mVerts[0] = p1;
00045       mVerts[1] = p2;
00046       mVerts[2] = p3;
00047    }
00048 
00054    Tri( const Tri<DATA_TYPE>& tri )
00055    {
00056       mVerts[0] = tri[0];
00057       mVerts[1] = tri[1];
00058       mVerts[2] = tri[2];
00059    }
00060 
00070    Point<DATA_TYPE, 3>& operator[]( const unsigned idx )
00071    {
00072       gmtlASSERT( idx <= 2 );
00073       return mVerts[idx];
00074    }
00075    const Point<DATA_TYPE, 3>& operator[]( const unsigned idx ) const
00076    {
00077       gmtlASSERT( idx <= 2 );
00078       return mVerts[idx];
00079    }
00081 
00092    Vec<DATA_TYPE, 3> edge( int idx ) const
00093    {
00094       gmtlASSERT( (0 <= idx) && (idx <= 2) );
00095       int idx2 = ( idx == 2 ) ? 0 : idx + 1;
00096       return (mVerts[idx2] - mVerts[idx]);
00097    }
00098 
00106    Vec<DATA_TYPE, 3> edge( int idx, int idy ) const
00107    {
00108       gmtlASSERT( (0 <= idx) && (idx <= 2) );
00109       gmtlASSERT( (0 <= idy) && (idy <= 2) );
00110       return (mVerts[idy] - mVerts[idx]);
00111    }
00112 
00113  
00114 
00125    void set( const Point<DATA_TYPE, 3>& p1, const Point<DATA_TYPE, 3>& p2,
00126            const Point<DATA_TYPE, 3>& p3 )
00127    {
00128       mVerts[0] = p1;
00129       mVerts[1] = p2;
00130       mVerts[2] = p3;
00131    }
00132 
00133 public:
00137    Point<DATA_TYPE, 3> mVerts[3];
00138 };
00139 
00140 // convenience typedefs
00141 typedef Tri<float> Trif;
00142 typedef Tri<double> Trid;
00143 typedef Tri<int> Trii;
00144 }
00145 
00146 /*
00147 // Finds the point on the seg nearest to pt.
00148 // on the perimeter of the triangle.
00149 // Returns the nearest point in nearPt
00150 inline
00151 void sgTri::findNearestEdgePt(const sgVec3& pt, sgVec3& nearPt) const
00152 {
00153     //      find all the closest pts on the segs that make the tri
00154     //      return the closest one
00155 
00156     sgSeg   seg1;   seg1.makePts(_v1, _v2);
00157     sgSeg   seg2;   seg2.makePts(_v2, _v3);
00158     sgSeg   seg3;   seg3.makePts(_v3, _v1);
00159 
00160     sgVec3  pt1;    seg1.findNearestPt(pt, pt1);
00161     sgVec3  pt2;    seg2.findNearestPt(pt, pt2);
00162     sgVec3  pt3;    seg3.findNearestPt(pt, pt3);
00163 
00164     float dist1 = SG_SQUARE(pt1[0]-pt[0]) + SG_SQUARE(pt1[1]-pt[1]) + SG_SQUARE(pt1[2]-pt[2]);
00165     float dist2 = SG_SQUARE(pt2[0]-pt[0]) + SG_SQUARE(pt2[1]-pt[1]) + SG_SQUARE(pt2[2]-pt[2]);
00166     float dist3 = SG_SQUARE(pt3[0]-pt[0]) + SG_SQUARE(pt3[1]-pt[1]) + SG_SQUARE(pt3[2]-pt[2]);
00167 
00168     if((dist1 < dist2) && (dist1 < dist3))      // dist1 is min
00169         nearPt = pt1;
00170     else if(dist2 < dist3)                      // dist2 is min
00171         nearPt = pt2;
00172     else
00173         nearPt = pt3;                           // dist3 is min
00174 }
00175 
00176 
00177 
00178    // Returns wether the pt is in the triangle
00179 inline
00180 int sgTri::ptIn(const sgVec3& pt) const
00181 {
00182       // Graphic Gems I: Page 392
00183    int i0, i1, i2;       // Axis indices
00184    float u0, u1, u2, v0, v1, v2, alpha, beta;
00185    i0 = 0;
00186    
00187     sgVec3  triNormal = (_v2-_v1).cross((_v3-_v1));
00188     //sgPlane triPlane;
00189     //triPlane.makePts(_v1, _v2, _v3);
00190 
00191    // Find max index
00192     // NOTE: note the fabs.  I added because of bug in GG code with negative normals
00193    for(int index=0;index<3;index++)
00194    if (fabs(triNormal.vec[index]) > fabs(triNormal.vec[i0]))
00195       i0 = index;
00196    
00197    if(i0 == 0)
00198       { i1 = 1; i2 = 2; }
00199    else if (i0 == 1)
00200       { i1 = 2; i2 = 0; }
00201    else
00202       { i1 =0; i2 = 1; }
00203    
00204    u0 = pt[i1] - _v1[i1];
00205    v0 = pt[i2] - _v1[i2];
00206    u1 = _v2[i1] - _v1[i1];
00207    u2 = _v3[i1] - _v1[i1];
00208    v1 = _v2[i2] - _v1[i2];
00209    v2 = _v3[i2] - _v1[i2];
00210    if(u1 == 0)
00211    {
00212       beta = (u0/u2);
00213       if((beta >= 0) && (beta<= 1))
00214          alpha = (v0 - (beta*v2))/v1;
00215    }
00216    else
00217    {
00218       beta = ((v0*u1) - (u0*v1))/((v2*u1) - (u2*v1));
00219       if((beta >= 0) && (beta<= 1))
00220          alpha = (u0 - (beta*u2))/u1;
00221    }
00222    
00223    return ((alpha >= 0) && (beta >= 0) && ((alpha+beta) <= 1));
00224 }
00225 
00226 
00227 
00228 // Finds the point on the seg nearest to pt.
00229 // Returns the nearest point in nearPt
00230 void sgTri::findNearestPt(const sgVec3& pt, sgVec3& nearPt) const
00231 {
00232         // find nearest pt on plaane.
00233         //      if it is in the tri, return it.
00234         // Otherwise return the pt closest on the edge of the tri
00235 
00236     sgPlane triPlane;
00237     triPlane.makePts(_v1, _v2, _v3);
00238     triPlane.findNearestPt(pt, nearPt);
00239 
00240     if(!ptIn(nearPt))
00241         findNearestEdgePt(pt, nearPt);
00242 }
00243 */
00244 
00245 #endif
00246 

Generated on Sun Sep 19 2010 14:35:14 for GenericMathTemplateLibrary by  doxygen 1.7.1