Back to index

salome-gui  6.5.0
GLViewer_Geom.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  Author : OPEN CASCADE
00024 //#include <GLViewerAfx.h>
00025 //
00026 #include "GLViewer_Geom.h"
00027 
00028 #define FAR_POINT 1e10  // Value used as a "very distant" co-ordinate
00029 #define TOLERANCE 1e-3
00030 
00034 GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt1, 
00035                                     const GLViewer_Pnt& thePnt2 )
00036 : myPnt1( thePnt1 ), 
00037   myPnt2( thePnt2 )
00038 {
00039   myA = myPnt1.y() - myPnt2.y();
00040   myB = myPnt2.x() - myPnt1.x();
00041   myC = myPnt1.x() * myPnt2.y() - myPnt2.x() * myPnt1.y();
00042 }
00043 
00047 GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt, 
00048                                     const GLfloat theA, 
00049                                     const GLfloat theB,
00050                                     const GLfloat theC )
00051 : myPnt1( thePnt ),
00052   myA( theA ),
00053   myB( theB ), 
00054   myC( theC )
00055 {
00056   if ( fabs( myB ) < TOLERANCE )
00057     myPnt2 = GLViewer_Pnt( myPnt1.x(), FAR_POINT );
00058   else
00059     myPnt2 = GLViewer_Pnt( FAR_POINT, - myA / myB * FAR_POINT - myC / myB );
00060 }
00061 
00065 GLViewer_Segment::~GLViewer_Segment()
00066 {
00067 }
00068 
00072 bool GLViewer_Segment::HasIntersection( const GLViewer_Segment& theOther ) const
00073 {
00074   bool aRes = false;
00075   GLfloat aDiv = myA * theOther.myB - myB * theOther.myA;
00076   if ( fabs( aDiv ) > TOLERANCE )
00077   {
00078     GLfloat aX  = ( myB * theOther.myC - theOther.myB * myC ) / aDiv;
00079     GLfloat aX11 = myPnt1.x() > myPnt2.x() ? myPnt2.x() : myPnt1.x();
00080     GLfloat aX12 = myPnt1.x() > myPnt2.x() ? myPnt1.x() : myPnt2.x();
00081     GLfloat aX21 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt2.x() : theOther.myPnt1.x();
00082     GLfloat aX22 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt1.x() : theOther.myPnt2.x();
00083 
00084     GLfloat aY  = ( myC * theOther.myA - theOther.myC * myA ) / aDiv;
00085     GLfloat aY11 = myPnt1.y() > myPnt2.y() ? myPnt2.y() : myPnt1.y();
00086     GLfloat aY12 = myPnt1.y() > myPnt2.y() ? myPnt1.y() : myPnt2.y();
00087     GLfloat aY21 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt2.y() : theOther.myPnt1.y();
00088     GLfloat aY22 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt1.y() : theOther.myPnt2.y();
00089 
00090     if ( fabs( aX11 - aX12 ) > TOLERANCE )
00091       aRes = aX11 < aX && aX < aX12;
00092     else
00093       aRes = aY11 < aY && aY < aY12;
00094 
00095     if ( aRes )
00096     {
00097       if ( fabs( aX21 - aX22 ) > TOLERANCE )
00098         aRes = aX21 < aX && aX < aX22;
00099       else
00100         aRes = aY21 < aY && aY < aY22;
00101     }
00102   }
00103 
00104   return aRes;
00105 }
00106 
00110 GLViewer_Poly::GLViewer_Poly( const GLViewer_PntList* thePoints )
00111 : myPoints( (GLViewer_PntList*)thePoints )
00112 {
00113 }
00114 
00118 GLViewer_Poly::~GLViewer_Poly()
00119 {
00120 }
00121 
00125 bool GLViewer_Poly::IsIn( const GLViewer_Pnt& thePnt ) const
00126 {
00127   if ( !myPoints )
00128     return false;
00129 
00130   //cout << thePnt.x() << endl;
00131   //cout << thePnt.y() << endl << endl;
00132 
00133   int aNbInter = 0;
00134   GLViewer_Segment aRay( thePnt, 0., 1., -thePnt.y() );
00135 
00136   GLViewer_PntList::const_iterator it1 = myPoints->begin();
00137   GLViewer_PntList::const_iterator it2 = myPoints->begin();
00138   ++it2;
00139   for ( ; it1 != myPoints->end(); ++it1, ++it2 )
00140   {
00141     if ( it2 == myPoints->end() )
00142       it2 = myPoints->begin();
00143     
00144     if ( aRay.HasIntersection( GLViewer_Segment( *it1, *it2 ) ) )
00145       aNbInter++;
00146   }
00147 
00148   return ( aNbInter % 2 == 1 );
00149 }
00153 /*
00154 bool GLViewer_Poly::IsIn( const GLViewer_Pnt& thePnt, const float tolerance ) const
00155 {
00156   if ( !myPoints )
00157     return false;
00158 
00159   float x = thePnt.x();
00160   float y = thePnt.y();
00161   bool res = false;
00162   
00163   GLViewer_Pnt p1( x - tolerance, y - tolerance );
00164   GLViewer_Pnt p2( x - tolerance, y + tolerance );
00165   GLViewer_Pnt p3( x + tolerance, y - tolerance );
00166   GLViewer_Pnt p4( x + tolerance, y + tolerance );
00167 
00168   res = ( IsInPnt( thePnt ) ||
00169           IsInPnt( p1 ) || IsInPnt( p2 ) || IsInPnt( p3 ) || IsInPnt( p4 ) );
00170 
00171   return res;
00172 }
00173 */
00177 bool GLViewer_Poly::IsCovers( const GLViewer_Poly& thePoly ) const
00178 {
00179     if ( !myPoints || !thePoly.Count() )
00180         return false;
00181 
00182     GLViewer_PntList::const_iterator it = myPoints->begin();
00183     
00184     for ( ; it != myPoints->end(); ++it )
00185     {
00186         if( !thePoly.IsIn( *it ) )
00187             return false;
00188     }
00189 
00190     return true;
00191 }
00192 
00196 bool GLViewer_Poly::IsCovers( const GLViewer_Rect& theRect ) const
00197 {
00198     if ( !myPoints ) //needs check for <theRect>
00199         return false;
00200 
00201     GLViewer_PntList aList;    
00202     GLViewer_PntList::iterator it = aList.begin();
00203     
00204     aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.top() ) );
00205     aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.top() ) );
00206     aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.bottom() ) );
00207     aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.bottom() ) );
00208 
00209     return IsCovers( GLViewer_Poly( &aList ) );
00210 }
00211 
00216 bool GLViewer_Poly::HasIntersection( const GLViewer_Segment& theSegment ) const
00217 {
00218   if ( !myPoints )
00219     return false;
00220 
00221   bool aRes = false;
00222   GLViewer_PntList::const_iterator it1 = myPoints->begin();
00223   GLViewer_PntList::const_iterator it2 = myPoints->begin();
00224   ++it2;
00225   for ( ; !aRes && it1 != myPoints->end(); ++it1, ++it2 )
00226   {
00227     if ( it2 == myPoints->end() )
00228       it2 = myPoints->begin();
00229     
00230     aRes = theSegment.HasIntersection( GLViewer_Segment( *it1, *it2 ) );
00231   }
00232 
00233   return aRes;
00234 }