]> git.saurik.com Git - wxWidgets.git/blame - src/common/geometry.cpp
Make code reading BMP files more robust.
[wxWidgets.git] / src / common / geometry.cpp
CommitLineData
07cdd027 1/////////////////////////////////////////////////////////////////////////////
e4db172a 2// Name: src/common/geometry.cpp
07cdd027
SC
3// Purpose: Common Geometry Classes
4// Author: Stefan Csomor
5// Modified by:
6// Created: 08/05/99
2903e699 7// RCS-ID: $Id$
11e82c1b 8// Copyright: (c) 1999 Stefan Csomor
65571936 9// Licence: wxWindows licence
07cdd027
SC
10/////////////////////////////////////////////////////////////////////////////
11
07cdd027
SC
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
07cdd027 15#ifdef __BORLANDC__
e4db172a 16 #pragma hdrstop
07cdd027
SC
17#endif
18
c3a4297c
VZ
19#if wxUSE_GEOMETRY
20
e4db172a
WS
21#include "wx/geometry.h"
22
23#ifndef WX_PRECOMP
24 #include "wx/log.h"
25#endif
26
07cdd027
SC
27#include <string.h>
28
07cdd027
SC
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
11e82c1b 43
07cdd027
SC
44bool wxRect2DDouble::Intersects( const wxRect2DDouble &rect ) const
45{
11e82c1b
VZ
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 {
5d3e7b52 54 return true;
11e82c1b 55 }
5d3e7b52 56 return false;
07cdd027
SC
57}
58
11e82c1b 59void wxRect2DDouble::Intersect( const wxRect2DDouble &src1 , const wxRect2DDouble &src2 , wxRect2DDouble *dest )
07cdd027 60{
11e82c1b
VZ
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 }
07cdd027
SC
78}
79
11e82c1b 80void wxRect2DDouble::Union( const wxRect2DDouble &src1 , const wxRect2DDouble &src2 , wxRect2DDouble *dest )
07cdd027 81{
11e82c1b
VZ
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;
07cdd027
SC
93}
94
11e82c1b 95void wxRect2DDouble::Union( const wxPoint2DDouble &pt )
07cdd027 96{
11e82c1b
VZ
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 }
07cdd027
SC
125}
126
127void wxRect2DDouble::ConstrainTo( const wxRect2DDouble &rect )
128{
11e82c1b
VZ
129 if ( GetLeft() < rect.GetLeft() )
130 SetLeft( rect.GetLeft() );
131
132 if ( GetRight() > rect.GetRight() )
133 SetRight( rect.GetRight() );
07cdd027 134
11e82c1b
VZ
135 if ( GetBottom() > rect.GetBottom() )
136 SetBottom( rect.GetBottom() );
07cdd027 137
11e82c1b
VZ
138 if ( GetTop() < rect.GetTop() )
139 SetTop( rect.GetTop() );
07cdd027
SC
140}
141
7dc85fe2
VZ
142wxRect2DDouble& 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
07cdd027
SC
151// integer version
152
153// for the following calculations always remember
154// that the right and bottom edges are not part of a rect
11e82c1b 155
07cdd027
SC
156// wxPoint2D
157
e30285ab 158#if wxUSE_STREAMS
07cdd027 159void wxPoint2DInt::WriteTo( wxDataOutputStream &stream ) const
11e82c1b
VZ
160{
161 stream.Write32( m_x );
162 stream.Write32( m_y );
07cdd027
SC
163}
164
11e82c1b
VZ
165void wxPoint2DInt::ReadFrom( wxDataInputStream &stream )
166{
167 m_x = stream.Read32();
168 m_y = stream.Read32();
07cdd027 169}
e30285ab 170#endif // wxUSE_STREAMS
07cdd027 171
2b5f62a0 172wxDouble wxPoint2DInt::GetVectorAngle() const
07cdd027 173{
11e82c1b
VZ
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
ade7e576
VZ
189 // casts needed for MIPSpro compiler under SGI
190 wxDouble deg = atan2( (double)m_y , (double)m_x ) * 180 / M_PI;
11e82c1b
VZ
191 if ( deg < 0 )
192 {
193 deg += 360;
194 }
195 return deg;
07cdd027
SC
196}
197
11e82c1b 198
ade7e576
VZ
199void 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 ));
adb1282e 204}
ade7e576 205
adb1282e
SC
206wxDouble wxPoint2DDouble::GetVectorAngle() const
207{
c77a6796 208 if ( wxIsNullDouble(m_x) )
ade7e576
VZ
209 {
210 if ( m_y >= 0 )
211 return 90;
212 else
213 return 270;
214 }
c77a6796 215 if ( wxIsNullDouble(m_y) )
ade7e576
VZ
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;
adb1282e
SC
228}
229
ade7e576
VZ
230void 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 );
adb1282e
SC
235}
236
07cdd027 237// wxRect2D
11e82c1b 238
07cdd027
SC
239bool wxRect2DInt::Intersects( const wxRect2DInt &rect ) const
240{
11e82c1b
VZ
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 {
5d3e7b52 249 return true;
11e82c1b 250 }
5d3e7b52 251 return false;
07cdd027
SC
252}
253
11e82c1b 254void wxRect2DInt::Intersect( const wxRect2DInt &src1 , const wxRect2DInt &src2 , wxRect2DInt *dest )
07cdd027 255{
11e82c1b
VZ
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 }
07cdd027
SC
273}
274
11e82c1b 275void wxRect2DInt::Union( const wxRect2DInt &src1 , const wxRect2DInt &src2 , wxRect2DInt *dest )
07cdd027 276{
11e82c1b
VZ
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;
07cdd027
SC
288}
289
11e82c1b 290void wxRect2DInt::Union( const wxPoint2DInt &pt )
07cdd027 291{
11e82c1b
VZ
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 }
07cdd027
SC
320}
321
322void wxRect2DInt::ConstrainTo( const wxRect2DInt &rect )
323{
11e82c1b
VZ
324 if ( GetLeft() < rect.GetLeft() )
325 SetLeft( rect.GetLeft() );
326
327 if ( GetRight() > rect.GetRight() )
328 SetRight( rect.GetRight() );
07cdd027 329
11e82c1b
VZ
330 if ( GetBottom() > rect.GetBottom() )
331 SetBottom( rect.GetBottom() );
07cdd027 332
11e82c1b
VZ
333 if ( GetTop() < rect.GetTop() )
334 SetTop( rect.GetTop() );
07cdd027
SC
335}
336
337wxRect2DInt& wxRect2DInt::operator=( const wxRect2DInt &r )
11e82c1b
VZ
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;
07cdd027
SC
344}
345
e30285ab 346#if wxUSE_STREAMS
07cdd027 347void wxRect2DInt::WriteTo( wxDataOutputStream &stream ) const
11e82c1b
VZ
348{
349 stream.Write32( m_x );
350 stream.Write32( m_y );
351 stream.Write32( m_width );
352 stream.Write32( m_height );
07cdd027
SC
353}
354
11e82c1b
VZ
355void 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();
07cdd027 361}
e30285ab 362#endif // wxUSE_STREAMS
07cdd027 363
a68c185d
VS
364
365// wxTransform2D
366
367void wxTransform2D::Transform( wxRect2DInt* r ) const
368{
369 wxPoint2DInt a = r->GetLeftTop(), b = r->GetRightBottom();
370 Transform( &a );
371 Transform( &b );
372 *r = wxRect2DInt( a, b );
373}
374
375wxPoint2DInt wxTransform2D::Transform( const wxPoint2DInt &pt ) const
376{
377 wxPoint2DInt res = pt;
378 Transform( &res );
379 return res;
380}
381
382wxRect2DInt wxTransform2D::Transform( const wxRect2DInt &r ) const
383{
384 wxRect2DInt res = r;
385 Transform( &res );
386 return res;
387}
388
389void wxTransform2D::InverseTransform( wxRect2DInt* r ) const
390{
391 wxPoint2DInt a = r->GetLeftTop(), b = r->GetRightBottom();
392 InverseTransform( &a );
393 InverseTransform( &b );
394 *r = wxRect2DInt( a , b );
395}
396
397wxPoint2DInt wxTransform2D::InverseTransform( const wxPoint2DInt &pt ) const
398{
399 wxPoint2DInt res = pt;
400 InverseTransform( &res );
401 return res;
402}
403
404wxRect2DInt wxTransform2D::InverseTransform( const wxRect2DInt &r ) const
405{
406 wxRect2DInt res = r;
407 InverseTransform( &res );
408 return res;
409}
410
c3a4297c 411#endif // wxUSE_GEOMETRY