# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1216811049 7200
# Node ID 0b0f802b14aa29a3c940ffaec1962cb24f2220ea
# Parent b6732e0d38c5c5e6b21123d8425a62591491e391
Improvements in dim2::BoundingBox (ticket #126)
 Rename the private varibles to start with underscore.
 Use LEMON_ASSERT() in setting functions to check the size invariant.
 Doc improvements.
diff r b6732e0d38c5 r 0b0f802b14aa lemon/dim2.h
a

b


20  20  #define LEMON_DIM2_H 
21  21  
22  22  #include <iostream> 
23   #include <lemon/core.h> 
 23  #include <lemon/assert.h> 
24  24  
25  25  ///\ingroup misc 
26  26  ///\file 
… 
… 

45  45  /// \addtogroup misc 
46  46  /// @{ 
47  47  
48   /// A simple two dimensional vector (plainvector) implementation 
 48  /// A simple two dimensional vector (plain vector) implementation 
49  49  
50   /// A simple two dimensional vector (plainvector) implementation 
 50  /// A simple two dimensional vector (plain vector) implementation 
51  51  /// with the usual vector operations. 
52  52  template<typename T> 
53  53  class Point { 
… 
… 

186  186  return x*u; 
187  187  } 
188  188  
189   ///Read a plainvector from a stream 
 189  ///Read a plain vector from a stream 
190  190  
191   ///Read a plainvector from a stream. 
 191  ///Read a plain vector from a stream. 
192  192  ///\relates Point 
193  193  /// 
194  194  template<typename T> 
… 
… 

214  214  return is; 
215  215  } 
216  216  
217   ///Write a plainvector to a stream 
 217  ///Write a plain vector to a stream 
218  218  
219   ///Write a plainvector to a stream. 
 219  ///Write a plain vector to a stream. 
220  220  ///\relates Point 
221  221  /// 
222  222  template<typename T> 
… 
… 

261  261  
262  262  
263  263  
264   /// A class to calculate or store the bounding box of plainvectors. 
 264  /// A class to calculate or store the bounding box of plain vectors. 
265  265  
266   /// A class to calculate or store the bounding box of plainvectors. 
267   /// 
 266  /// A class to calculate or store the bounding box of plain vectors. 
 267  /// 
268  268  template<typename T> 
269  269  class BoundingBox { 
270   Point<T> bottom_left, top_right; 
 270  Point<T> _bottom_left, _top_right; 
271  271  bool _empty; 
272  272  public: 
273  273  
… 
… 

275  275  BoundingBox() { _empty = true; } 
276  276  
277  277  ///Construct an instance from one point 
278   BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; } 
 278  BoundingBox(Point<T> a) { 
 279  _bottom_left = _top_right = a; 
 280  _empty = false; 
 281  } 
279  282  
280  283  ///Construct an instance from two points 
281  284  
… 
… 

286  289  ///than those of the top right one. 
287  290  BoundingBox(Point<T> a,Point<T> b) 
288  291  { 
289   bottom_left=a; 
290   top_right=b; 
 292  _bottom_left = a; 
 293  _top_right = b; 
291  294  _empty = false; 
 295  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 296  _bottom_left.y <= _top_right.y, 
 297  "The size invariant is violated"); 
292  298  } 
293  299  
294  300  ///Construct an instance from four numbers 
… 
… 

302  308  ///bottom must be no more than the top. 
303  309  BoundingBox(T l,T b,T r,T t) 
304  310  { 
305   bottom_left=Point<T>(l,b); 
306   top_right=Point<T>(r,t); 
 311  _bottom_left=Point<T>(l,b); 
 312  _top_right=Point<T>(r,t); 
307  313  _empty = false; 
 314  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 315  _bottom_left.y <= _top_right.y, 
 316  "The size invariant is violated"); 
308  317  } 
309  318  
310  319  ///Return \c true if the bounding box is empty. 
… 
… 

320  329  
321  330  ///Make the BoundingBox empty 
322  331  void clear() { 
323   _empty=1; 
 332  _empty = true; 
324  333  } 
325  334  
326  335  ///Give back the bottom left corner of the box 
… 
… 

328  337  ///Give back the bottom left corner of the box. 
329  338  ///If the bounding box is empty, then the return value is not defined. 
330  339  Point<T> bottomLeft() const { 
331   return bottom_left; 
 340  return _bottom_left; 
332  341  } 
333  342  
334  343  ///Set the bottom left corner of the box 
335  344  
336  345  ///Set the bottom left corner of the box. 
337   ///It should only be used for nonempty box. 
 346  ///\warning It should only be used for nonempty box. 
338  347  void bottomLeft(Point<T> p) { 
339   bottom_left = p; 
 348  _bottom_left = p; 
 349  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 350  _bottom_left.y <= _top_right.y, 
 351  "The size invariant is violated"); 
340  352  } 
341  353  
342  354  ///Give back the top right corner of the box 
… 
… 

344  356  ///Give back the top right corner of the box. 
345  357  ///If the bounding box is empty, then the return value is not defined. 
346  358  Point<T> topRight() const { 
347   return top_right; 
 359  return _top_right; 
348  360  } 
349  361  
350  362  ///Set the top right corner of the box 
351  363  
352  364  ///Set the top right corner of the box. 
353   ///It should only be used for nonempty box. 
 365  ///\warning It should only be used for nonempty box. 
354  366  void topRight(Point<T> p) { 
355   top_right = p; 
 367  _top_right = p; 
 368  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 369  _bottom_left.y <= _top_right.y, 
 370  "The size invariant is violated"); 
356  371  } 
357  372  
358  373  ///Give back the bottom right corner of the box 
… 
… 

360  375  ///Give back the bottom right corner of the box. 
361  376  ///If the bounding box is empty, then the return value is not defined. 
362  377  Point<T> bottomRight() const { 
363   return Point<T>(top_right.x,bottom_left.y); 
 378  return Point<T>(_top_right.x,_bottom_left.y); 
364  379  } 
365  380  
366  381  ///Set the bottom right corner of the box 
367  382  
368  383  ///Set the bottom right corner of the box. 
369   ///It should only be used for nonempty box. 
 384  ///\warning It should only be used for nonempty box. 
370  385  void bottomRight(Point<T> p) { 
371   top_right.x = p.x; 
372   bottom_left.y = p.y; 
 386  _top_right.x = p.x; 
 387  _bottom_left.y = p.y; 
 388  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 389  _bottom_left.y <= _top_right.y, 
 390  "The size invariant is violated"); 
373  391  } 
374  392  
375  393  ///Give back the top left corner of the box 
… 
… 

377  395  ///Give back the top left corner of the box. 
378  396  ///If the bounding box is empty, then the return value is not defined. 
379  397  Point<T> topLeft() const { 
380   return Point<T>(bottom_left.x,top_right.y); 
 398  return Point<T>(_bottom_left.x,_top_right.y); 
381  399  } 
382  400  
383  401  ///Set the top left corner of the box 
384  402  
385  403  ///Set the top left corner of the box. 
386   ///It should only be used for nonempty box. 
 404  ///\warning It should only be used for nonempty box. 
387  405  void topLeft(Point<T> p) { 
388   top_right.y = p.y; 
389   bottom_left.x = p.x; 
 406  _top_right.y = p.y; 
 407  _bottom_left.x = p.x; 
 408  LEMON_ASSERT(_bottom_left.x <= _top_right.x && 
 409  _bottom_left.y <= _top_right.y, 
 410  "The size invariant is violated"); 
390  411  } 
391  412  
392  413  ///Give back the bottom of the box 
… 
… 

394  415  ///Give back the bottom of the box. 
395  416  ///If the bounding box is empty, then the return value is not defined. 
396  417  T bottom() const { 
397   return bottom_left.y; 
 418  return _bottom_left.y; 
398  419  } 
399  420  
400  421  ///Set the bottom of the box 
401  422  
402  423  ///Set the bottom of the box. 
403   ///It should only be used for nonempty box. 
 424  ///\warning It should only be used for nonempty box. 
404  425  void bottom(T t) { 
405   bottom_left.y = t; 
 426  _bottom_left.y = t; 
 427  LEMON_ASSERT(_bottom_left.y <= _top_right.y, 
 428  "The size invariant is violated"); 
406  429  } 
407  430  
408  431  ///Give back the top of the box 
… 
… 

410  433  ///Give back the top of the box. 
411  434  ///If the bounding box is empty, then the return value is not defined. 
412  435  T top() const { 
413   return top_right.y; 
 436  return _top_right.y; 
414  437  } 
415  438  
416  439  ///Set the top of the box 
417  440  
418  441  ///Set the top of the box. 
419   ///It should only be used for nonempty box. 
 442  ///\warning It should only be used for nonempty box. 
420  443  void top(T t) { 
421   top_right.y = t; 
 444  _top_right.y = t; 
 445  LEMON_ASSERT(_bottom_left.y <= _top_right.y, 
 446  "The size invariant is violated"); 
422  447  } 
423  448  
424  449  ///Give back the left side of the box 
… 
… 

426  451  ///Give back the left side of the box. 
427  452  ///If the bounding box is empty, then the return value is not defined. 
428  453  T left() const { 
429   return bottom_left.x; 
 454  return _bottom_left.x; 
430  455  } 
431  456  
432  457  ///Set the left side of the box 
433  458  
434  459  ///Set the left side of the box. 
435   ///It should only be used for nonempty box. 
 460  ///\warning It should only be used for nonempty box. 
436  461  void left(T t) { 
437   bottom_left.x = t; 
 462  _bottom_left.x = t; 
 463  LEMON_ASSERT(_bottom_left.x <= _top_right.x, 
 464  "The size invariant is violated"); 
438  465  } 
439  466  
440  467  /// Give back the right side of the box 
… 
… 

442  469  /// Give back the right side of the box. 
443  470  ///If the bounding box is empty, then the return value is not defined. 
444  471  T right() const { 
445   return top_right.x; 
 472  return _top_right.x; 
446  473  } 
447  474  
448  475  ///Set the right side of the box 
449  476  
450  477  ///Set the right side of the box. 
451   ///It should only be used for nonempty box. 
 478  ///\warning It should only be used for nonempty box. 
452  479  void right(T t) { 
453   top_right.x = t; 
 480  _top_right.x = t; 
 481  LEMON_ASSERT(_bottom_left.x <= _top_right.x, 
 482  "The size invariant is violated"); 
454  483  } 
455  484  
456  485  ///Give back the height of the box 
… 
… 

458  487  ///Give back the height of the box. 
459  488  ///If the bounding box is empty, then the return value is not defined. 
460  489  T height() const { 
461   return top_right.ybottom_left.y; 
 490  return _top_right.y_bottom_left.y; 
462  491  } 
463  492  
464  493  ///Give back the width of the box 
… 
… 

466  495  ///Give back the width of the box. 
467  496  ///If the bounding box is empty, then the return value is not defined. 
468  497  T width() const { 
469   return top_right.xbottom_left.x; 
 498  return _top_right.x_bottom_left.x; 
470  499  } 
471  500  
472  501  ///Checks whether a point is inside a bounding box 
473  502  bool inside(const Point<T>& u) const { 
474  503  if (_empty) 
475  504  return false; 
476   else{ 
477   return ((u.xbottom_left.x)*(top_right.xu.x) >= 0 && 
478   (u.ybottom_left.y)*(top_right.yu.y) >= 0 ); 
 505  else { 
 506  return ( (u.x_bottom_left.x)*(_top_right.xu.x) >= 0 && 
 507  (u.y_bottom_left.y)*(_top_right.yu.y) >= 0 ); 
479  508  } 
480  509  } 
481  510  
… 
… 

484  513  ///Increments a bounding box with a point. 
485  514  /// 
486  515  BoundingBox& add(const Point<T>& u){ 
487   if (_empty){ 
488   bottom_left=top_right=u; 
 516  if (_empty) { 
 517  _bottom_left = _top_right = u; 
489  518  _empty = false; 
490  519  } 
491   else{ 
492   if (bottom_left.x > u.x) bottom_left.x = u.x; 
493   if (bottom_left.y > u.y) bottom_left.y = u.y; 
494   if (top_right.x < u.x) top_right.x = u.x; 
495   if (top_right.y < u.y) top_right.y = u.y; 
 520  else { 
 521  if (_bottom_left.x > u.x) _bottom_left.x = u.x; 
 522  if (_bottom_left.y > u.y) _bottom_left.y = u.y; 
 523  if (_top_right.x < u.x) _top_right.x = u.x; 
 524  if (_top_right.y < u.y) _top_right.y = u.y; 
496  525  } 
497  526  return *this; 
498  527  } 
… 
… 

503  532  /// 
504  533  BoundingBox& add(const BoundingBox &u){ 
505  534  if ( !u.empty() ){ 
506   this>add(u.bottomLeft()); 
507   this>add(u.topRight()); 
 535  add(u._bottom_left); 
 536  add(u._top_right); 
508  537  } 
509  538  return *this; 
510  539  } 
… 
… 

515  544  /// 
516  545  BoundingBox operator&(const BoundingBox& u) const { 
517  546  BoundingBox b; 
518   if (this>_empty  u._empty) { 
 547  if (_empty  u._empty) { 
519  548  b._empty = true; 
520  549  } else { 
521   b.bottom_left.x = std::max(this>bottom_left.x,u.bottom_left.x); 
522   b.bottom_left.y = std::max(this>bottom_left.y,u.bottom_left.y); 
523   b.top_right.x = std::min(this>top_right.x,u.top_right.x); 
524   b.top_right.y = std::min(this>top_right.y,u.top_right.y); 
525   b._empty = b.bottom_left.x > b.top_right.x  
526   b.bottom_left.y > b.top_right.y; 
 550  b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x); 
 551  b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y); 
 552  b._top_right.x = std::min(_top_right.x, u._top_right.x); 
 553  b._top_right.y = std::min(_top_right.y, u._top_right.y); 
 554  b._empty = b._bottom_left.x > b._top_right.x  
 555  b._bottom_left.y > b._top_right.y; 
527  556  } 
528  557  return b; 
529  558  } 