1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/common/geometry.cpp
3 // Purpose:     Common Geometry Classes
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     08/05/99
7 // RCS-ID:
8 // Copyright:   (c) 1999 Stefan Csomor
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14 
15 #ifdef __BORLANDC__
16     #pragma hdrstop
17 #endif
18 
19 #if wxUSE_GEOMETRY
20 
21 #include "wx/geometry.h"
22 
23 #ifndef WX_PRECOMP
24     #include "wx/log.h"
25 #endif
26 
27 #include <string.h>
28 
29 #include "wx/datstrm.h"
30 
31 //
32 // wxPoint2D
33 //
34 
35 //
36 // wxRect2D
37 //
38 
39 // wxDouble version
40 
41 // for the following calculations always remember
42 // that the right and bottom edges are not part of a rect
43 
Intersects(const wxRect2DDouble & rect) const44 bool wxRect2DDouble::Intersects( const wxRect2DDouble &rect ) const
45 {
46     wxDouble left,right,bottom,top;
47     left = wxMax ( m_x , rect.m_x );
48     right = wxMin ( m_x+m_width, rect.m_x + rect.m_width );
49     top = wxMax ( m_y , rect.m_y );
50     bottom = wxMin ( m_y+m_height, rect.m_y + rect.m_height );
51 
52     if ( left < right && top < bottom )
53     {
54         return true;
55     }
56     return false;
57 }
58 
Intersect(const wxRect2DDouble & src1,const wxRect2DDouble & src2,wxRect2DDouble * dest)59 void wxRect2DDouble::Intersect( const wxRect2DDouble &src1 , const wxRect2DDouble &src2 , wxRect2DDouble *dest )
60 {
61     wxDouble left,right,bottom,top;
62     left = wxMax ( src1.m_x , src2.m_x );
63     right = wxMin ( src1.m_x+src1.m_width, src2.m_x + src2.m_width );
64     top = wxMax ( src1.m_y , src2.m_y );
65     bottom = wxMin ( src1.m_y+src1.m_height, src2.m_y + src2.m_height );
66 
67     if ( left < right && top < bottom )
68     {
69         dest->m_x = left;
70         dest->m_y = top;
71         dest->m_width = right - left;
72         dest->m_height = bottom - top;
73     }
74     else
75     {
76         dest->m_width = dest->m_height = 0;
77     }
78 }
79 
Union(const wxRect2DDouble & src1,const wxRect2DDouble & src2,wxRect2DDouble * dest)80 void wxRect2DDouble::Union( const wxRect2DDouble &src1 , const wxRect2DDouble &src2 , wxRect2DDouble *dest )
81 {
82     wxDouble left,right,bottom,top;
83 
84     left = wxMin ( src1.m_x , src2.m_x );
85     right = wxMax ( src1.m_x+src1.m_width, src2.m_x + src2.m_width );
86     top = wxMin ( src1.m_y , src2.m_y );
87     bottom = wxMax ( src1.m_y+src1.m_height, src2.m_y + src2.m_height );
88 
89     dest->m_x = left;
90     dest->m_y = top;
91     dest->m_width = right - left;
92     dest->m_height = bottom - top;
93 }
94 
Union(const wxPoint2DDouble & pt)95 void wxRect2DDouble::Union( const wxPoint2DDouble &pt )
96 {
97     wxDouble x = pt.m_x;
98     wxDouble y = pt.m_y;
99 
100     if ( x < m_x )
101     {
102         SetLeft( x );
103     }
104     else if ( x < m_x + m_width )
105     {
106         // contained
107     }
108     else
109     {
110         SetRight( x );
111     }
112 
113     if ( y < m_y )
114     {
115         SetTop( y );
116     }
117     else if ( y < m_y + m_height )
118     {
119         // contained
120     }
121     else
122     {
123         SetBottom( y );
124     }
125 }
126 
ConstrainTo(const wxRect2DDouble & rect)127 void wxRect2DDouble::ConstrainTo( const wxRect2DDouble &rect )
128 {
129     if ( GetLeft() < rect.GetLeft() )
130         SetLeft( rect.GetLeft() );
131 
132     if ( GetRight() > rect.GetRight() )
133         SetRight( rect.GetRight() );
134 
135     if ( GetBottom() > rect.GetBottom() )
136         SetBottom( rect.GetBottom() );
137 
138     if ( GetTop() < rect.GetTop() )
139         SetTop( rect.GetTop() );
140 }
141 
operator =(const wxRect2DDouble & r)142 wxRect2DDouble& wxRect2DDouble::operator=( const wxRect2DDouble &r )
143 {
144     m_x = r.m_x;
145     m_y = r.m_y;
146     m_width = r.m_width;
147     m_height = r.m_height;
148     return *this;
149 }
150 
151 // integer version
152 
153 // for the following calculations always remember
154 // that the right and bottom edges are not part of a rect
155 
156 // wxPoint2D
157 
158 #if wxUSE_STREAMS
WriteTo(wxDataOutputStream & stream) const159 void wxPoint2DInt::WriteTo( wxDataOutputStream &stream ) const
160 {
161     stream.Write32( m_x );
162     stream.Write32( m_y );
163 }
164 
ReadFrom(wxDataInputStream & stream)165 void wxPoint2DInt::ReadFrom( wxDataInputStream &stream )
166 {
167     m_x = stream.Read32();
168     m_y = stream.Read32();
169 }
170 #endif // wxUSE_STREAMS
171 
GetVectorAngle() const172 wxDouble wxPoint2DInt::GetVectorAngle() const
173 {
174     if ( m_x == 0 )
175     {
176         if ( m_y >= 0 )
177             return 90;
178         else
179             return 270;
180     }
181     if ( m_y == 0 )
182     {
183         if ( m_x >= 0 )
184             return 0;
185         else
186             return 180;
187     }
188 
189     // casts needed for MIPSpro compiler under SGI
190     wxDouble deg = atan2( (double)m_y , (double)m_x ) * 180 / M_PI;
191     if ( deg < 0 )
192     {
193         deg += 360;
194     }
195     return deg;
196 }
197 
198 
SetVectorAngle(wxDouble degrees)199 void wxPoint2DInt::SetVectorAngle( wxDouble degrees )
200 {
201     wxDouble length = GetVectorLength();
202     m_x = (int)(length * cos( degrees / 180 * M_PI ));
203     m_y = (int)(length * sin( degrees / 180 * M_PI ));
204 }
205 
GetVectorAngle() const206 wxDouble wxPoint2DDouble::GetVectorAngle() const
207 {
208     if ( wxIsNullDouble(m_x) )
209     {
210         if ( m_y >= 0 )
211             return 90;
212         else
213             return 270;
214     }
215     if ( wxIsNullDouble(m_y) )
216     {
217         if ( m_x >= 0 )
218             return 0;
219         else
220             return 180;
221     }
222     wxDouble deg = atan2( m_y , m_x ) * 180 / M_PI;
223     if ( deg < 0 )
224     {
225         deg += 360;
226     }
227     return deg;
228 }
229 
SetVectorAngle(wxDouble degrees)230 void wxPoint2DDouble::SetVectorAngle( wxDouble degrees )
231 {
232     wxDouble length = GetVectorLength();
233     m_x = length * cos( degrees / 180 * M_PI );
234     m_y = length * sin( degrees / 180 * M_PI );
235 }
236 
237 // wxRect2D
238 
Intersects(const wxRect2DInt & rect) const239 bool wxRect2DInt::Intersects( const wxRect2DInt &rect ) const
240 {
241     wxInt32 left,right,bottom,top;
242     left = wxMax ( m_x , rect.m_x );
243     right = wxMin ( m_x+m_width, rect.m_x + rect.m_width );
244     top = wxMax ( m_y , rect.m_y );
245     bottom = wxMin ( m_y+m_height, rect.m_y + rect.m_height );
246 
247     if ( left < right && top < bottom )
248     {
249         return true;
250     }
251     return false;
252 }
253 
Intersect(const wxRect2DInt & src1,const wxRect2DInt & src2,wxRect2DInt * dest)254 void wxRect2DInt::Intersect( const wxRect2DInt &src1 , const wxRect2DInt &src2 , wxRect2DInt *dest )
255 {
256     wxInt32 left,right,bottom,top;
257     left = wxMax ( src1.m_x , src2.m_x );
258     right = wxMin ( src1.m_x+src1.m_width, src2.m_x + src2.m_width );
259     top = wxMax ( src1.m_y , src2.m_y );
260     bottom = wxMin ( src1.m_y+src1.m_height, src2.m_y + src2.m_height );
261 
262     if ( left < right && top < bottom )
263     {
264         dest->m_x = left;
265         dest->m_y = top;
266         dest->m_width = right - left;
267         dest->m_height = bottom - top;
268     }
269     else
270     {
271         dest->m_width = dest->m_height = 0;
272     }
273 }
274 
Union(const wxRect2DInt & src1,const wxRect2DInt & src2,wxRect2DInt * dest)275 void wxRect2DInt::Union( const wxRect2DInt &src1 , const wxRect2DInt &src2 , wxRect2DInt *dest )
276 {
277     wxInt32 left,right,bottom,top;
278 
279     left = wxMin ( src1.m_x , src2.m_x );
280     right = wxMax ( src1.m_x+src1.m_width, src2.m_x + src2.m_width );
281     top = wxMin ( src1.m_y , src2.m_y );
282     bottom = wxMax ( src1.m_y+src1.m_height, src2.m_y + src2.m_height );
283 
284     dest->m_x = left;
285     dest->m_y = top;
286     dest->m_width = right - left;
287     dest->m_height = bottom - top;
288 }
289 
Union(const wxPoint2DInt & pt)290 void wxRect2DInt::Union( const wxPoint2DInt &pt )
291 {
292     wxInt32 x = pt.m_x;
293     wxInt32 y = pt.m_y;
294 
295     if ( x < m_x )
296     {
297         SetLeft( x );
298     }
299     else if ( x < m_x + m_width )
300     {
301         // contained
302     }
303     else
304     {
305         SetRight( x );
306     }
307 
308     if ( y < m_y )
309     {
310         SetTop( y );
311     }
312     else if ( y < m_y + m_height )
313     {
314         // contained
315     }
316     else
317     {
318         SetBottom( y );
319     }
320 }
321 
ConstrainTo(const wxRect2DInt & rect)322 void wxRect2DInt::ConstrainTo( const wxRect2DInt &rect )
323 {
324     if ( GetLeft() < rect.GetLeft() )
325         SetLeft( rect.GetLeft() );
326 
327     if ( GetRight() > rect.GetRight() )
328         SetRight( rect.GetRight() );
329 
330     if ( GetBottom() > rect.GetBottom() )
331         SetBottom( rect.GetBottom() );
332 
333     if ( GetTop() < rect.GetTop() )
334         SetTop( rect.GetTop() );
335 }
336 
operator =(const wxRect2DInt & r)337 wxRect2DInt& wxRect2DInt::operator=( const wxRect2DInt &r )
338 {
339     m_x = r.m_x;
340     m_y = r.m_y;
341     m_width = r.m_width;
342     m_height = r.m_height;
343     return *this;
344 }
345 
346 #if wxUSE_STREAMS
WriteTo(wxDataOutputStream & stream) const347 void wxRect2DInt::WriteTo( wxDataOutputStream &stream ) const
348 {
349     stream.Write32( m_x );
350     stream.Write32( m_y );
351     stream.Write32( m_width );
352     stream.Write32( m_height );
353 }
354 
ReadFrom(wxDataInputStream & stream)355 void wxRect2DInt::ReadFrom( wxDataInputStream &stream )
356 {
357     m_x = stream.Read32();
358     m_y = stream.Read32();
359     m_width = stream.Read32();
360     m_height = stream.Read32();
361 }
362 #endif // wxUSE_STREAMS
363 
364 #endif // wxUSE_GEOMETRY
365