wxArt2D
bbox.cpp
Go to the documentation of this file.
1 /*! \file artbase/src/bbox.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2000-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: bbox.cpp,v 1.16 2009/06/05 19:41:03 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20 
21 #include "wx/artbase/bbox.h"
22 
24 
26 {
27  m_minx = m_miny = m_maxx = m_maxy = 0.0;
28  m_validbbox = false;
29 }
30 
31 
33 {
34  m_minx = other.m_minx;
35  m_miny = other.m_miny;
36  m_maxx = other.m_maxx;
37  m_maxy = other.m_maxy;
38  m_validbbox = other.m_validbbox;
39 }
40 
41 
43 {
44  m_validbbox = false;
45  Expand( a.m_x, a.m_y );
46 }
47 
48 a2dBoundingBox::a2dBoundingBox( double x1, double y1, double x2, double y2 )
49 {
50  m_validbbox = false;
51  Expand( x1, y1 );
52  Expand( x2, y2 );
53 }
54 
55 // This function intersects
56 bool a2dBoundingBox::And( a2dBoundingBox* bbox, double Marge )
57 {
58  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
59  wxASSERT_MSG( bbox->m_validbbox, wxT( "invalid bbox" ) );
60 
61  if ( ( ( m_minx - Marge ) > ( bbox->m_maxx + Marge ) ) ||
62  ( ( m_maxx + Marge ) < ( bbox->m_minx - Marge ) ) ||
63  ( ( m_maxy + Marge ) < ( bbox->m_miny - Marge ) ) ||
64  ( ( m_miny - Marge ) > ( bbox->m_maxy + Marge ) ) )
65  return false;
66 
67  // Check if other.bbox is inside this bbox
68  if ( ( m_minx <= bbox->m_minx ) &&
69  ( m_maxx >= bbox->m_maxx ) &&
70  ( m_maxy >= bbox->m_maxy ) &&
71  ( m_miny <= bbox->m_miny ) )
72  {
73  m_minx = bbox->m_minx;
74  m_maxx = bbox->m_maxx;
75  m_miny = bbox->m_miny;
76  m_maxy = bbox->m_maxy;
77  return true;
78  }
79 
80  //overlap
81  m_minx = wxMax( m_minx, bbox->m_minx );
82  m_maxx = wxMin( m_maxx, bbox->m_maxx );
83  m_miny = wxMax( m_miny, bbox->m_miny );
84  m_maxy = wxMin( m_maxy, bbox->m_maxy );
85  return true;
86 }
87 
88 // Shrink the boundingbox with the given marge
89 void a2dBoundingBox::Shrink( const double Marge )
90 {
91  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
92 
93  m_minx += Marge;
94  m_maxx -= Marge;
95  m_miny += Marge;
96  m_maxy -= Marge;
97 }
98 
99 
100 // Expand the boundingbox with another boundingbox
102 {
103  if ( !m_validbbox )
104  {
105  *this = other;
106  }
107  else
108  {
109  m_minx = wxMin( m_minx, other.m_minx );
110  m_maxx = wxMax( m_maxx, other.m_maxx );
111  m_miny = wxMin( m_miny, other.m_miny );
112  m_maxy = wxMax( m_maxy, other.m_maxy );
113  }
114 }
115 
116 
117 // Expand the boundingbox with a point
118 void a2dBoundingBox::Expand( const a2dPoint2D& a_point )
119 {
120  if ( !m_validbbox )
121  {
122  m_minx = m_maxx = a_point.m_x;
123  m_miny = m_maxy = a_point.m_y;
124  m_validbbox = true;
125  }
126  else
127  {
128  m_minx = wxMin( m_minx, a_point.m_x );
129  m_maxx = wxMax( m_maxx, a_point.m_x );
130  m_miny = wxMin( m_miny, a_point.m_y );
131  m_maxy = wxMax( m_maxy, a_point.m_y );
132  }
133 }
134 
135 // Expand the boundingbox with a point
136 void a2dBoundingBox::Expand( double x, double y )
137 {
138  if ( !m_validbbox )
139  {
140  m_minx = m_maxx = x;
141  m_miny = m_maxy = y;
142  m_validbbox = true;
143  }
144  else
145  {
146  m_minx = wxMin( m_minx, x );
147  m_maxx = wxMax( m_maxx, x );
148  m_miny = wxMin( m_miny, y );
149  m_maxy = wxMax( m_maxy, y );
150  }
151 }
152 
153 
154 // Expand the boundingbox with two points
155 void a2dBoundingBox::Expand( const a2dPoint2D& a, const a2dPoint2D& b )
156 {
157  Expand( a );
158  Expand( b );
159 }
160 
161 // Enlarge the boundingbox with the given marge
162 void a2dBoundingBox::Enlarge( const double marge )
163 {
164  if ( !m_validbbox )
165  {
166  m_minx = -marge;
167  m_miny = -marge;
168  m_maxx = marge;
169  m_maxy = marge;
170  m_validbbox = true;
171  }
172  else
173  {
174  m_minx -= marge;
175  m_maxx += marge;
176  m_miny -= marge;
177  m_maxy += marge;
178  }
179 }
180 
181 // Enlarge the boundingbox with the given marge
182 void a2dBoundingBox::EnlargeXY( const double margeX, const double margeY )
183 {
184  if ( !m_validbbox )
185  {
186  m_minx = -margeX;
187  m_miny = -margeY;
188  m_maxx = margeX;
189  m_maxy = margeY;
190  m_validbbox = true;
191  }
192  else
193  {
194  m_minx -= margeX;
195  m_maxx += margeX;
196  m_miny -= margeY;
197  m_maxy += margeY;
198  }
199 }
200 
201 // Calculates if two boundingboxes intersect. If so, the function returns _ON.
202 // If they do not intersect, two scenario's are possible:
203 // other is outside this -> return _OUT
204 // other is inside this -> return _IN
205 OVERLAP a2dBoundingBox::Intersect( const a2dBoundingBox& other, double Marge ) const
206 {
207  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
208  wxASSERT_MSG( other.m_validbbox, wxT( "invalid bbox" ) );
209 
210 
211  if ( ( ( m_minx - Marge ) > ( other.m_maxx + Marge ) ) ||
212  ( ( m_maxx + Marge ) < ( other.m_minx - Marge ) ) ||
213  ( ( m_maxy + Marge ) < ( other.m_miny - Marge ) ) ||
214  ( ( m_miny - Marge ) > ( other.m_maxy + Marge ) ) )
215  return _OUT;
216 
217  // Check if other.bbox is inside this bbox
218  if ( ( m_minx <= other.m_minx + Marge ) &&
219  ( m_maxx >= other.m_maxx - Marge ) &&
220  ( m_maxy >= other.m_maxy - Marge ) &&
221  ( m_miny <= other.m_miny + Marge ) )
222  return _IN;
223 
224  // Boundingboxes intersect
225  return _ON;
226 }
227 
228 
229 // Checks if a line intersects the boundingbox
230 bool a2dBoundingBox::LineIntersect( const a2dPoint2D& begin, const a2dPoint2D& end ) const
231 {
232  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
233 
234  return ( bool )
235  !( ( ( begin.m_y > m_maxy ) && ( end.m_y > m_maxy ) ) ||
236  ( ( begin.m_y < m_miny ) && ( end.m_y < m_miny ) ) ||
237  ( ( begin.m_x > m_maxx ) && ( end.m_x > m_maxx ) ) ||
238  ( ( begin.m_x < m_minx ) && ( end.m_x < m_minx ) ) );
239 }
240 
241 
242 // Is the given point in the boundingbox ??
243 bool a2dBoundingBox::PointInBox( double x, double y, double Marge ) const
244 {
245  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
246 
247  if ( x >= ( m_minx - Marge ) && x <= ( m_maxx + Marge ) &&
248  y >= ( m_miny - Marge ) && y <= ( m_maxy + Marge ) )
249  return true;
250  return false;
251 }
252 
253 //
254 // Is the given point in the boundingbox ??
255 //
256 bool a2dBoundingBox::PointInBox( const a2dPoint2D& a, double Marge ) const
257 {
258  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
259 
260  return PointInBox( a.m_x, a.m_y, Marge );
261 }
262 
263 // Is the given point in the boundingbox ??
264 bool a2dBoundingBox::PointOnBox( double x, double y, double Marge ) const
265 {
266  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
267 
268  if ( x >= ( m_minx - Marge ) && x <= ( m_maxx + Marge ) &&
269  y >= ( m_miny - Marge ) && y <= ( m_maxy + Marge ) &&
270  ( x <= ( m_minx + Marge ) || x >= ( m_maxx - Marge ) ||
271  y <= ( m_miny + Marge ) || y >= ( m_maxy - Marge ) )
272  )
273  return true;
274  return false;
275 }
276 
278 {
279  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
280 
281  return a2dPoint2D( (m_maxx + m_minx)/2.0, (m_maxy + m_miny)/2.0 );
282 }
283 
285 {
286  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
287 
288  return a2dPoint2D( m_minx, m_miny );
289 }
290 
291 
293 {
294  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
295 
296  return a2dPoint2D( m_maxx, m_maxy );
297 }
298 
300 {
301  return m_validbbox;
302 }
303 
305 {
306  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
307  return m_minx;
308 }
309 
311 {
312  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
313  return m_miny;
314 }
315 
317 {
318  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
319  return m_maxx;
320 }
321 
323 {
324  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
325  return m_maxy;
326 }
327 
329 {
330  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
331  return fabs( m_maxx - m_minx );
332 }
333 
335 {
336  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
337  return fabs( m_maxy - m_miny );
338 }
339 
340 void a2dBoundingBox::SetMin( double px, double py )
341 {
342  m_minx = px;
343  m_miny = py;
344  if ( !m_validbbox )
345  {
346  m_maxx = px;
347  m_maxy = py;
348  m_validbbox = true;
349  }
350 }
351 
352 void a2dBoundingBox::SetMax( double px, double py )
353 {
354  m_maxx = px;
355  m_maxy = py;
356  if ( !m_validbbox )
357  {
358  m_minx = px;
359  m_miny = py;
360  m_validbbox = true;
361  }
362 }
363 
364 void a2dBoundingBox::SetValid( bool value )
365 {
366  m_validbbox = value;
367 }
368 
369 // usage : a_boundingbox.Translate(a_point);
371 {
372  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
373 
374  m_minx += offset.m_x;
375  m_maxx += offset.m_x;
376  m_miny += offset.m_y;
377  m_maxy += offset.m_y;
378  return *this;
379 }
380 
381 const a2dBoundingBox& a2dBoundingBox::Translate( double x, double y )
382 {
383  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
384 
385  m_minx += x;
386  m_maxx += x;
387  m_miny += y;
388  m_maxy += y;
389  return *this;
390 }
391 
392 
393 // clears the bounding box settings
395 {
396  m_minx = 0.0;
397  m_maxx = 0.0;
398  m_miny = 0.0;
399  m_maxy = 0.0;
400  m_validbbox = false;
401 }
402 
403 
405 {
406  m_minx = a_point.m_x;
407  m_maxx = a_point.m_x;
408  m_miny = a_point.m_y;
409  m_maxy = a_point.m_y;
410 }
411 
413 {
414  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
415  wxASSERT_MSG( other.m_validbbox, wxT( "invalid bbox" ) );
416 
417  Expand( other );
418  return *this;
419 }
420 
422 {
423  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
424  wxASSERT_MSG( box.m_validbbox, wxT( "invalid bbox" ) );
425 
426  Expand( box );
427  return *this;
428 }
429 
430 // makes a boundingbox same as the other
432 {
433  //DO not assert here, an invalid boudingbox should be copied without problems.
434  //It is used for initializing in certain cases.
435  //wxASSERT_MSG( other.m_validbbox, wxT("invalid bbox") );
436 
437  m_minx = other.m_minx;
438  m_maxx = other.m_maxx;
439  m_miny = other.m_miny;
440  m_maxy = other.m_maxy;
441  m_validbbox = other.m_validbbox;
442  return *this;
443 }
444 
446 {
447  wxASSERT_MSG( m_validbbox, wxT( "invalid bbox" ) );
448 
449  if ( matrix.IsIdentity() )
450  return;
451 
452  double x1, y1, x2, y2, x3, y3, x4, y4;
453 
454  matrix.TransformPoint( m_minx, m_miny, x1, y1 );
455  matrix.TransformPoint( m_minx, m_maxy, x2, y2 );
456  matrix.TransformPoint( m_maxx, m_maxy, x3, y3 );
457  matrix.TransformPoint( m_maxx, m_miny, x4, y4 );
458 
459  m_minx = wxMin( x1, x2 );
460  m_minx = wxMin( m_minx, x3 );
461  m_minx = wxMin( m_minx, x4 );
462 
463  m_maxx = wxMax( x1, x2 );
464  m_maxx = wxMax( m_maxx, x3 );
465  m_maxx = wxMax( m_maxx, x4 );
466 
467  m_miny = wxMin( y1, y2 );
468  m_miny = wxMin( m_miny, y3 );
469  m_miny = wxMin( m_miny, y4 );
470 
471  m_maxy = wxMax( y1, y2 );
472  m_maxy = wxMax( m_maxy, y3 );
473  m_maxy = wxMax( m_maxy, y4 );
474 }
475 
476 #ifdef _DEBUG
477 
478 void a2dBoundingBox::Dump() const
479 {
480  wxLogDebug( _T( "boundingbox minx=%f, miny=%f maxx=%f maxy=%f" ), m_minx, m_miny, m_maxx, m_maxy );
481  wxLogDebug( _T( "boundingbox width=%f, height=%f" ), GetWidth(), GetHeight() );
482 }
483 
484 #endif
485 
486 
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
double GetHeight() const
returns height of the boundingbox
Definition: bbox.cpp:334
a2dPoint2D GetCentre() const
get centre
Definition: bbox.cpp:277
bool PointOnBox(double x, double y, double Marge) const
is the coordinate on the border of the boundingbox
Definition: bbox.cpp:264
void SetValid(bool)
Definition: bbox.cpp:364
OVERLAP Intersect(const a2dBoundingBox &, double Marge=0) const
Definition: bbox.cpp:205
void Enlarge(const double Marge)
enlarge with the given amount
Definition: bbox.cpp:162
a2dPoint2D GetMin() const
get the bounding box its minimum
Definition: bbox.cpp:284
bool IsIdentity(void) const
Is the matrix the identity matrix?
Definition: afmatrix.h:147
OVERLAP
Result of a a2dBoundingBox intersection or hittest.
Definition: bbox.h:24
const a2dBoundingBox & operator+=(const a2dBoundingBox &box)
OR box to this.
Definition: bbox.cpp:421
a2dBoundingBox wxNonValidBbox
global non valid boundingbox to use as default argument etc.
Definition: bbox.cpp:23
bool m_validbbox
true if boundingbox is valid
Definition: bbox.h:194
bool And(a2dBoundingBox *, double Marge=0)
intersect the boundingbox with another, return true if the result is non zero
Definition: bbox.cpp:56
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
Definition: afmatrix.cpp:559
a2dPoint2D GetMax() const
get the bounding box its maximum
Definition: bbox.cpp:292
bool GetValid() const
returns true if boundingbox is calculated properly and therefore its valid flag is set...
Definition: bbox.cpp:299
void Expand(const a2dPoint2D &, const a2dPoint2D &)
expand boundingbox width two points
Definition: bbox.cpp:155
const a2dBoundingBox & Translate(a2dPoint2D &)
translate with given vector
Definition: bbox.cpp:370
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
void Reset()
set invalid
Definition: bbox.cpp:394
Definition: bbox.h:26
bounding class for optimizing drawing speed.
void Shrink(const double Marge)
shrink with the given amount
Definition: bbox.cpp:89
Definition: bbox.h:27
a2dBoundingBox()
constructor
Definition: bbox.cpp:25
void SetMin(double px, double py)
set the bounding box its maximum
Definition: bbox.cpp:340
bool LineIntersect(const a2dPoint2D &begin, const a2dPoint2D &end) const
Definition: bbox.cpp:230
double m_maxx
maximum X of bounding box in world coordinates
Definition: bbox.h:189
bool PointInBox(const a2dPoint2D &, double Marge=0) const
is the point within the boundingbox
Definition: bbox.cpp:256
void SetBoundingBox(const a2dPoint2D &a_point)
set the bounding box to be this point
Definition: bbox.cpp:404
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
double GetMaxX() const
get maximum X of the boundingbox
Definition: bbox.cpp:316
a2dBoundingBox & operator+(a2dBoundingBox &)
And operation on two boxes.
Definition: bbox.cpp:412
void SetMax(double px, double py)
set the bounding box its minimum
Definition: bbox.cpp:352
void MapBbox(const a2dAffineMatrix &matrix)
Definition: bbox.cpp:445
Definition: bbox.h:28
double GetMaxY() const
get maximum Y of the boundingbox
Definition: bbox.cpp:322
double GetWidth() const
returns width of the boundingbox
Definition: bbox.cpp:328
double m_maxy
maximum Y of bounding box in world coordinates
Definition: bbox.h:191
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
void EnlargeXY(const double MargeX, const double MargeY)
enlarge with the given amount
Definition: bbox.cpp:182
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
double m_miny
mininum Y of bounding box in world coordinates
Definition: bbox.h:187
a2dBoundingBox & operator=(const a2dBoundingBox &)
set this boundingbox to another boundingbox
Definition: bbox.cpp:431
double m_minx
mininum X of bounding box in world coordinates
Definition: bbox.h:185
bbox.cpp Source File -- Sun Oct 12 2014 17:04:12 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation