Wm4Intersector1.cpp

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 #include "Wm4FoundationPCH.h"
00018 #include "Wm4Intersector1.h"
00019 
00020 namespace Wm4
00021 {
00022 //----------------------------------------------------------------------------
00023 template <class Real>
00024 Intersector1<Real>::Intersector1 (Real fU0, Real fU1, Real fV0, Real fV1)
00025 {
00026     assert(fU0 <= fU1 && fV0 <= fV1);
00027     m_afU[0] = fU0;
00028     m_afU[1] = fU1;
00029     m_afV[0] = fV0;
00030     m_afV[1] = fV1;
00031     m_fFirstTime = (Real)0.0;
00032     m_fLastTime = (Real)0.0;
00033     m_iQuantity = 0;
00034 }
00035 //----------------------------------------------------------------------------
00036 template <class Real>
00037 Intersector1<Real>::Intersector1 (Real afU[2], Real afV[2])
00038 {
00039     assert(afU[0] <= afU[1] && afV[0] <= afV[1]);
00040     for (int i = 0; i < 2; i++)
00041     {
00042         m_afU[i] = afU[i];
00043         m_afV[i] = afV[i];
00044     }
00045     m_fFirstTime = (Real)0.0;
00046     m_fLastTime = (Real)0.0;
00047     m_iQuantity = 0;
00048 }
00049 //----------------------------------------------------------------------------
00050 template <class Real>
00051 Intersector1<Real>::~Intersector1 ()
00052 {
00053 }
00054 //----------------------------------------------------------------------------
00055 template <class Real>
00056 Real Intersector1<Real>::GetU (int i) const
00057 {
00058     assert(0 <= i && i < 2);
00059     return m_afU[i];
00060 }
00061 //----------------------------------------------------------------------------
00062 template <class Real>
00063 Real Intersector1<Real>::GetV (int i) const
00064 {
00065     assert(0 <= i && i < 2);
00066     return m_afV[i];
00067 }
00068 //----------------------------------------------------------------------------
00069 template <class Real>
00070 bool Intersector1<Real>::Test ()
00071 {
00072     return m_afU[0] <= m_afV[1] && m_afU[1] >= m_afV[0];
00073 }
00074 //----------------------------------------------------------------------------
00075 template <class Real>
00076 bool Intersector1<Real>::Find ()
00077 {
00078     if (m_afU[1] < m_afV[0] || m_afU[0] > m_afV[1])
00079     {
00080         m_iQuantity = 0;
00081     }
00082     else if (m_afU[1] > m_afV[0])
00083     {
00084         if (m_afU[0] < m_afV[1])
00085         {
00086             m_iQuantity = 2;
00087             m_afOverlap[0] = (m_afU[0] < m_afV[0] ? m_afV[0] : m_afU[0]);
00088             m_afOverlap[1] = (m_afU[1] > m_afV[1] ? m_afV[1] : m_afU[1]);
00089             if (m_afOverlap[0] == m_afOverlap[1])
00090             {
00091                 m_iQuantity = 1;
00092             }
00093         }
00094         else  // m_afU[0] == m_afV[1]
00095         {
00096             m_iQuantity = 1;
00097             m_afOverlap[0] = m_afU[0];
00098         }
00099     }
00100     else  // m_afU[1] == m_afV[0]
00101     {
00102         m_iQuantity = 1;
00103         m_afOverlap[0] = m_afU[1];
00104     }
00105 
00106     return m_iQuantity > 0;
00107 }
00108 //----------------------------------------------------------------------------
00109 template <class Real>
00110 bool Intersector1<Real>::Test (Real fTMax, Real fSpeedU, Real fSpeedV)
00111 {
00112     Real fDiffSpeed, fInvDiffSpeed, fDiffPos;
00113 
00114     if (m_afU[1] < m_afV[0])
00115     {
00116         // [u0,u1] initially to the left of [v0,v1]
00117         fDiffSpeed = fSpeedU - fSpeedV;
00118         if (fDiffSpeed > (Real)0.0)
00119         {
00120             // the intervals must move towards each other
00121             fDiffPos = m_afV[0] - m_afU[1];
00122             if (fDiffPos <= fTMax*fDiffSpeed)
00123             {
00124                 // the intervals intersect within the specified time
00125                 fInvDiffSpeed = ((Real)1.0)/fDiffSpeed;
00126                 m_fFirstTime = fDiffPos*fInvDiffSpeed;
00127                 m_fLastTime = (m_afV[1] - m_afU[0])*fInvDiffSpeed;
00128                 return true;
00129             }
00130         }
00131     }
00132     else if (m_afU[0] > m_afV[1])
00133     {
00134         // [u0,u1] initially to the right of [v0,v1]
00135         fDiffSpeed = fSpeedV - fSpeedU;
00136         if ( fDiffSpeed > (Real)0.0 )
00137         {
00138             // the intervals must move towards each other
00139             fDiffPos = m_afU[0] - m_afV[1];
00140             if (fDiffPos <= fTMax*fDiffSpeed)
00141             {
00142                 // the intervals intersect within the specified time
00143                 fInvDiffSpeed = ((Real)1.0)/fDiffSpeed;
00144                 m_fFirstTime = fDiffPos*fInvDiffSpeed;
00145                 m_fLastTime = (m_afU[1] - m_afV[0])*fInvDiffSpeed;
00146                 return true;
00147             }
00148         }
00149     }
00150     else
00151     {
00152         // the intervals are initially intersecting
00153         m_fFirstTime = 0.0f;
00154         if (fSpeedV > fSpeedU)
00155         {
00156             m_fLastTime = (m_afU[1] - m_afV[0])/(fSpeedV - fSpeedU);
00157         }
00158         else if (fSpeedV < fSpeedU)
00159         {
00160             m_fLastTime = (m_afV[1] - m_afU[0])/(fSpeedU - fSpeedV);
00161         }
00162         else
00163         {
00164             m_fLastTime = Math<Real>::MAX_REAL;
00165         }
00166 
00167         return true;
00168     }
00169 
00170     return false;
00171 }
00172 //----------------------------------------------------------------------------
00173 template <class Real>
00174 bool Intersector1<Real>::Find (Real fTMax, Real fSpeedU, Real fSpeedV)
00175 {
00176     Real fDiffSpeed, fInvDiffSpeed, fDiffPos;
00177 
00178     if (m_afU[1] < m_afV[0])
00179     {
00180         // [u0,u1] initially to the left of [v0,v1]
00181         fDiffSpeed = fSpeedU - fSpeedV;
00182         if (fDiffSpeed > (Real)0.0)
00183         {
00184             // the intervals must move towards each other
00185             fDiffPos = m_afV[0] - m_afU[1];
00186             if (fDiffPos <= fTMax*fDiffSpeed)
00187             {
00188                 // the intervals intersect within the specified time
00189                 fInvDiffSpeed = ((Real)1.0)/fDiffSpeed;
00190                 m_fFirstTime = fDiffPos*fInvDiffSpeed;
00191                 m_fLastTime = (m_afV[1] - m_afU[0])*fInvDiffSpeed;
00192                 m_iQuantity = 1;
00193                 m_afOverlap[0] = m_afU[0] + m_fFirstTime*fSpeedU;
00194                 return true;
00195             }
00196         }
00197     }
00198     else if (m_afU[0] > m_afV[1])
00199     {
00200         // [u0,u1] initially to the right of [v0,v1]
00201         fDiffSpeed = fSpeedV - fSpeedU;
00202         if (fDiffSpeed > (Real)0.0)
00203         {
00204             // the intervals must move towards each other
00205             fDiffPos = m_afU[0] - m_afV[1];
00206             if (fDiffPos <= fTMax*fDiffSpeed)
00207             {
00208                 // the intervals intersect within the specified time
00209                 fInvDiffSpeed = ((Real)1.0)/fDiffSpeed;
00210                 m_fFirstTime = fDiffPos*fInvDiffSpeed;
00211                 m_fLastTime = (m_afU[1] - m_afV[0])*fInvDiffSpeed;
00212                 m_iQuantity = 1;
00213                 m_afOverlap[0] = m_afV[1] + m_fFirstTime*fSpeedV;
00214                 return true;
00215             }
00216         }
00217     }
00218     else
00219     {
00220         // the intervals are initially intersecting
00221         m_fFirstTime = 0.0f;
00222         if (fSpeedV > fSpeedU)
00223         {
00224             m_fLastTime = (m_afU[1] - m_afV[0])/(fSpeedV - fSpeedU);
00225         }
00226         else if (fSpeedV < fSpeedU)
00227         {
00228             m_fLastTime = (m_afV[1] - m_afU[0])/(fSpeedU - fSpeedV);
00229         }
00230         else
00231         {
00232             m_fLastTime = Math<Real>::MAX_REAL;
00233         }
00234 
00235         if (m_afU[1] > m_afV[0])
00236         {
00237             if (m_afU[0] < m_afV[1])
00238             {
00239                 m_iQuantity = 2;
00240                 m_afOverlap[0] = (m_afU[0] < m_afV[0] ? m_afV[0] : m_afU[0]);
00241                 m_afOverlap[1] = (m_afU[1] > m_afV[1] ? m_afV[1] : m_afU[1]);
00242             }
00243             else  // m_afU[0] == m_afV[1]
00244             {
00245                 m_iQuantity = 1;
00246                 m_afOverlap[0] = m_afU[0];
00247             }
00248         }
00249         else  // m_afU[1] == m_afV[0]
00250         {
00251             m_iQuantity = 1;
00252             m_afOverlap[0] = m_afU[1];
00253         }
00254         return true;
00255     }
00256 
00257     m_iQuantity = 0;
00258     return false;
00259 }
00260 //----------------------------------------------------------------------------
00261 template <class Real>
00262 Real Intersector1<Real>::GetFirstTime () const
00263 {
00264     return m_fFirstTime;
00265 }
00266 //----------------------------------------------------------------------------
00267 template <class Real>
00268 Real Intersector1<Real>::GetLastTime () const
00269 {
00270     return m_fLastTime;
00271 }
00272 //----------------------------------------------------------------------------
00273 template <class Real>
00274 int Intersector1<Real>::GetQuantity () const
00275 {
00276     return m_iQuantity;
00277 }
00278 //----------------------------------------------------------------------------
00279 template <class Real>
00280 Real Intersector1<Real>::GetOverlap (int i) const
00281 {
00282     assert(0 <= i && i < m_iQuantity);
00283     return m_afOverlap[i];
00284 }
00285 //----------------------------------------------------------------------------
00286 
00287 //----------------------------------------------------------------------------
00288 // explicit instantiation
00289 //----------------------------------------------------------------------------
00290 template WM4_FOUNDATION_ITEM
00291 class Intersector1<float>;
00292 
00293 template WM4_FOUNDATION_ITEM
00294 class Intersector1<double>;
00295 //----------------------------------------------------------------------------
00296 }

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