1 // File: GLViewer_Detector.cxx
2 // Created: 11/16/2004 14:19:07
3 // Author: Sergey ANIKIN
6 #include <GLViewer_Detector.h>
8 #define FAR_POINT 1e10 // Value used as a "very distant" co-ordinate
11 //================================================================
12 // Class : GLViewer_Segment
14 //================================================================
16 //================================================================
17 // Function : GLViewer_Segment
18 // Purpose : constructs a real segment bounded by two points
19 //================================================================
20 GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt1,
21 const GLViewer_Pnt& thePnt2 )
25 myA = myPnt1.y() - myPnt2.y();
26 myB = myPnt2.x() - myPnt1.x();
27 myC = myPnt1.x() * myPnt2.y() - myPnt2.x() * myPnt1.y();
30 //================================================================
31 // Function : GLViewer_Segment
32 // Purpose : constructs a ray starting at <thePnt> and directed
33 // along positive X axis direction (or Y axis if vertical )
34 //================================================================
35 GLViewer_Segment::GLViewer_Segment( const GLViewer_Pnt& thePnt,
44 if ( fabs( myB ) < TOLERANCE )
45 myPnt2 = GLViewer_Pnt( myPnt1.x(), FAR_POINT );
47 myPnt2 = GLViewer_Pnt( FAR_POINT, - myA / myB * FAR_POINT - myC / myB );
50 //================================================================
51 // Function : GLViewer_Segment
52 // Purpose : destructor, does nothing
53 //================================================================
54 GLViewer_Segment::~GLViewer_Segment()
58 //================================================================
59 // Function : HasIntersection
60 // Purpose : detects intersection with segment <theOther>
61 //================================================================
62 bool GLViewer_Segment::HasIntersection( const GLViewer_Segment& theOther ) const
65 GLfloat aDiv = myA * theOther.myB - myB * theOther.myA;
66 if ( fabs( aDiv ) > TOLERANCE )
68 GLfloat aX = ( myB * theOther.myC - theOther.myB * myC ) / aDiv;
69 GLfloat aX11 = myPnt1.x() > myPnt2.x() ? myPnt2.x() : myPnt1.x();
70 GLfloat aX12 = myPnt1.x() > myPnt2.x() ? myPnt1.x() : myPnt2.x();
71 GLfloat aX21 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt2.x() : theOther.myPnt1.x();
72 GLfloat aX22 = theOther.myPnt1.x() > theOther.myPnt2.x() ? theOther.myPnt1.x() : theOther.myPnt2.x();
74 GLfloat aY = ( myC * theOther.myA - theOther.myC * myA ) / aDiv;
75 GLfloat aY11 = myPnt1.y() > myPnt2.y() ? myPnt2.y() : myPnt1.y();
76 GLfloat aY12 = myPnt1.y() > myPnt2.y() ? myPnt1.y() : myPnt2.y();
77 GLfloat aY21 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt2.y() : theOther.myPnt1.y();
78 GLfloat aY22 = theOther.myPnt1.y() > theOther.myPnt2.y() ? theOther.myPnt1.y() : theOther.myPnt2.y();
80 if ( fabs( aX11 - aX12 ) > TOLERANCE )
81 aRes = aX11 < aX && aX < aX12;
83 aRes = aY11 < aY && aY < aY12;
87 if ( fabs( aX21 - aX22 ) > TOLERANCE )
88 aRes = aX21 < aX && aX < aX22;
90 aRes = aY21 < aY && aY < aY22;
97 //================================================================
98 // Class : GLViewer_Poly
100 //================================================================
102 //================================================================
103 // Function : GLViewer_Poly
104 // Purpose : constructs a closed polygon from the given ordered list of points
105 //================================================================
106 GLViewer_Poly::GLViewer_Poly( const GLViewer_PntList* thePoints )
107 : myPoints( (GLViewer_PntList*)thePoints )
111 //================================================================
112 // Function : ~GLViewer_Poly
113 // Purpose : destructor, <myPoints> mustn't be deleted here!
114 //================================================================
115 GLViewer_Poly::~GLViewer_Poly()
119 //================================================================
121 // Purpose : returns true if <thePnt> lies within this polygon
122 //================================================================
123 bool GLViewer_Poly::IsIn( const GLViewer_Pnt& thePnt ) const
129 GLViewer_Segment aRay( thePnt, 0., 1., -thePnt.y() );
131 GLViewer_PntList::const_iterator it1 = myPoints->begin();
132 GLViewer_PntList::const_iterator it2 = myPoints->begin();
134 for ( ; it1 != myPoints->end(); ++it1, ++it2 )
136 if ( it2 == myPoints->end() )
137 it2 = myPoints->begin();
139 if ( aRay.HasIntersection( GLViewer_Segment( *it1, *it2 ) ) )
143 return ( aNbInter % 2 == 1 );
146 //================================================================
147 // Function : IsCovers
148 // Purpose : returns true if <thePoly> covers this polygon
149 //================================================================
150 bool GLViewer_Poly::IsCovers( const GLViewer_Poly& thePoly ) const
152 if ( !myPoints || !thePoly.Count() )
155 GLViewer_PntList::const_iterator it = myPoints->begin();
157 for ( ; it != myPoints->end(); ++it )
159 if( !thePoly.IsIn( *it ) )
166 //================================================================
167 // Function : IsCovers
168 // Purpose : returns true if <theRect> covers this polygon
169 //================================================================
170 bool GLViewer_Poly::IsCovers( const GLViewer_Rect& theRect ) const
172 if ( !myPoints ) //needs check for <theRect>
175 GLViewer_PntList aList;
176 GLViewer_PntList::iterator it = aList.begin();
178 aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.top() ) );
179 aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.top() ) );
180 aList.insert( it, GLViewer_Pnt( theRect.right(), theRect.bottom() ) );
181 aList.insert( it, GLViewer_Pnt( theRect.left(), theRect.bottom() ) );
183 return IsCovers( GLViewer_Poly( &aList ) );
186 //================================================================
187 // Function : HasIntersection
188 // Purpose : looks for any
189 //================================================================
190 bool GLViewer_Poly::HasIntersection( const GLViewer_Segment& theSegment ) const
196 GLViewer_PntList::const_iterator it1 = myPoints->begin();
197 GLViewer_PntList::const_iterator it2 = myPoints->begin();
199 for ( ; !aRes && it1 != myPoints->end(); ++it1, ++it2 )
201 if ( it2 == myPoints->end() )
202 it2 = myPoints->begin();
204 aRes = theSegment.HasIntersection( GLViewer_Segment( *it1, *it2 ) );