Wm4Mapper3.inl

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 namespace Wm4
00018 {
00019 //----------------------------------------------------------------------------
00020 template <class Real>
00021 Mapper3<Real>::Mapper3 (int iVQuantity, const Vector3<Real>* akVertex,
00022     Real fEpsilon)
00023 {
00024     assert(iVQuantity > 0 && akVertex && fEpsilon >= (Real)0.0);
00025     m_bExtremeCCW = false;
00026 
00027     // Compute the axis-aligned bounding box for the input points.
00028     m_kMin = akVertex[0];
00029     m_kMax = m_kMin;
00030 
00031     int aiIMin[3], aiIMax[3], i, j;
00032     for (j = 0; j < 3; j++)
00033     {
00034         aiIMin[j] = 0;
00035         aiIMax[j] = 0;
00036     }
00037 
00038     for (i = 1; i < iVQuantity; i++)
00039     {
00040         for (j = 0; j < 3; j++)
00041         {
00042             if (akVertex[i][j] < m_kMin[j])
00043             {
00044                 m_kMin[j] = akVertex[i][j];
00045                 aiIMin[j] = i;
00046             }
00047             else if (akVertex[i][j] > m_kMax[j])
00048             {
00049                 m_kMax[j] = akVertex[i][j];
00050                 aiIMax[j] = i;
00051             }
00052         }
00053     }
00054 
00055     // Determine the maximum range for the bounding box.
00056     Vector3<Real> kRange = m_kMax - m_kMin;
00057     m_fMaxRange = kRange[0];
00058     m_aiExtreme[0] = aiIMin[0];
00059     m_aiExtreme[1] = aiIMax[0];
00060     if (kRange[1] > m_fMaxRange)
00061     {
00062         m_fMaxRange = kRange[1];
00063         m_aiExtreme[0] = aiIMin[1];
00064         m_aiExtreme[1] = aiIMax[1];
00065     }
00066     if (kRange[2] > m_fMaxRange)
00067     {
00068         m_fMaxRange = kRange[2];
00069         m_aiExtreme[0] = aiIMin[2];
00070         m_aiExtreme[1] = aiIMax[2];
00071     }
00072     m_kOrigin = akVertex[m_aiExtreme[0]];
00073 
00074     // Test if the point set is (nearly) a point.
00075     if (m_fMaxRange < fEpsilon)
00076     {
00077         m_iDimension = 0;
00078         m_aiExtreme[1] = m_aiExtreme[0];
00079         m_aiExtreme[2] = m_aiExtreme[0];
00080         m_aiExtreme[3] = m_aiExtreme[0];
00081         m_akDirection[0] = Vector3<Real>::ZERO;
00082         m_akDirection[1] = Vector3<Real>::ZERO;
00083         m_akDirection[2] = Vector3<Real>::ZERO;
00084         return;
00085     }
00086 
00087     // Test if the point set is (nearly) a line segment.
00088     m_akDirection[0] = akVertex[m_aiExtreme[1]] - m_kOrigin;
00089     m_akDirection[0].Normalize();
00090     Real fLMax = (Real)0.0, fL, fDot;
00091     m_aiExtreme[2] = m_aiExtreme[0];
00092     for (i = 0; i < iVQuantity; i++)
00093     {
00094         Vector3<Real> kDiff = akVertex[i] - m_kOrigin;
00095         fDot = m_akDirection[0].Dot(kDiff);
00096         Vector3<Real> kProj = kDiff - fDot*m_akDirection[0];
00097         fL = kProj.Length();
00098         if (fL > fLMax)
00099         {
00100             fLMax = fL;
00101             m_aiExtreme[2] = i;
00102         }
00103     }
00104 
00105     if (fLMax < fEpsilon*m_fMaxRange)
00106     {
00107         m_iDimension = 1;
00108         m_aiExtreme[2] = m_aiExtreme[1];
00109         m_aiExtreme[3] = m_aiExtreme[1];
00110         m_akDirection[1] = Vector3<Real>::ZERO;
00111         m_akDirection[2] = Vector3<Real>::ZERO;
00112         return;
00113     }
00114 
00115     // Test if the point set is (nearly) a planar polygon.
00116     m_akDirection[1] = akVertex[m_aiExtreme[2]] - m_kOrigin;
00117     fDot = m_akDirection[0].Dot(m_akDirection[1]);
00118     m_akDirection[1] -= fDot*m_akDirection[0];
00119     m_akDirection[1].Normalize();
00120     m_akDirection[2] = m_akDirection[0].Cross(m_akDirection[1]);
00121     fLMax = (Real)0.0;
00122     Real fMaxSign = (Real)0.0, fSign;
00123     m_aiExtreme[3] = m_aiExtreme[0];
00124     for (i = 0; i < iVQuantity; i++)
00125     {
00126         Vector3<Real> kDiff = akVertex[i] - m_kOrigin;
00127         fL = m_akDirection[2].Dot(kDiff);
00128         fSign = Math<Real>::Sign(fL);
00129         fL = Math<Real>::FAbs(fL);
00130         if (fL > fLMax)
00131         {
00132             fLMax = fL;
00133             fMaxSign = fSign;
00134             m_aiExtreme[3] = i;
00135         }
00136     }
00137 
00138     if (fLMax < fEpsilon*m_fMaxRange)
00139     {
00140         m_iDimension = 2;
00141         m_aiExtreme[3] = m_aiExtreme[2];
00142         return;
00143     }
00144 
00145     m_iDimension = 3;
00146     m_bExtremeCCW = (fMaxSign > (Real)0.0 ? true : false);
00147 }
00148 //----------------------------------------------------------------------------
00149 template <class Real>
00150 Mapper3<Real>::~Mapper3 ()
00151 {
00152 }
00153 //----------------------------------------------------------------------------
00154 template <class Real>
00155 const Vector3<Real>& Mapper3<Real>::GetMin () const
00156 {
00157     return m_kMin;
00158 }
00159 //----------------------------------------------------------------------------
00160 template <class Real>
00161 const Vector3<Real>& Mapper3<Real>::GetMax () const
00162 {
00163     return m_kMax;
00164 }
00165 //----------------------------------------------------------------------------
00166 template <class Real>
00167 Real Mapper3<Real>::GetMaxRange () const
00168 {
00169     return m_fMaxRange;
00170 }
00171 //----------------------------------------------------------------------------
00172 template <class Real>
00173 int Mapper3<Real>::GetDimension () const
00174 {
00175     return m_iDimension;
00176 }
00177 //----------------------------------------------------------------------------
00178 template <class Real>
00179 const Vector3<Real>& Mapper3<Real>::GetOrigin () const
00180 {
00181     return m_kOrigin;
00182 }
00183 //----------------------------------------------------------------------------
00184 template <class Real>
00185 const Vector3<Real>& Mapper3<Real>::GetDirection (int i) const
00186 {
00187     assert(0 <= i && i < 3);
00188     return m_akDirection[i];
00189 }
00190 //----------------------------------------------------------------------------
00191 template <class Real>
00192 int Mapper3<Real>::GetExtremeIndex (int i) const
00193 {
00194     assert(0 <= i && i < 4);
00195     return m_aiExtreme[i];
00196 }
00197 //----------------------------------------------------------------------------
00198 template <class Real>
00199 bool Mapper3<Real>::GetExtremeCCW () const
00200 {
00201     return m_bExtremeCCW;
00202 }
00203 //----------------------------------------------------------------------------
00204 } //namespace Wm4

Generated on Wed Nov 23 19:01:04 2011 for FreeCAD by  doxygen 1.6.1