gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements in dim2::BoundingBox (ticket #126) - Rename the private varibles to start with underscore. - Doc improvements.
0 1 0
default
1 file changed with 66 insertions and 64 deletions:
↑ Collapse diff ↑
Ignore white space 24 line context
... ...
@@ -11,52 +11,51 @@
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_DIM2_H
20 20
#define LEMON_DIM2_H
21 21

	
22 22
#include <iostream>
23
#include <lemon/core.h>
24 23

	
25 24
///\ingroup misc
26 25
///\file
27 26
///\brief A simple two dimensional vector and a bounding box implementation
28 27
///
29 28
/// The class \ref lemon::dim2::Point "dim2::Point" implements
30 29
/// a two dimensional vector with the usual operations.
31 30
///
32 31
/// The class \ref lemon::dim2::BoundingBox "dim2::BoundingBox"
33 32
/// can be used to determine
34 33
/// the rectangular bounding box of a set of
35 34
/// \ref lemon::dim2::Point "dim2::Point"'s.
36 35

	
37 36
namespace lemon {
38 37

	
39 38
  ///Tools for handling two dimensional coordinates
40 39

	
41 40
  ///This namespace is a storage of several
42 41
  ///tools for handling two dimensional coordinates
43 42
  namespace dim2 {
44 43

	
45 44
  /// \addtogroup misc
46 45
  /// @{
47 46

	
48
  /// A simple two dimensional vector (plainvector) implementation
47
  /// A simple two dimensional vector (plain vector) implementation
49 48

	
50
  /// A simple two dimensional vector (plainvector) implementation
49
  /// A simple two dimensional vector (plain vector) implementation
51 50
  /// with the usual vector operations.
52 51
  template<typename T>
53 52
    class Point {
54 53

	
55 54
    public:
56 55

	
57 56
      typedef T Value;
58 57

	
59 58
      ///First coordinate
60 59
      T x;
61 60
      ///Second coordinate
62 61
      T y;
... ...
@@ -177,27 +176,27 @@
177 176
  inline Point<T> makePoint(const T& x, const T& y) {
178 177
    return Point<T>(x, y);
179 178
  }
180 179

	
181 180
  ///Return a vector multiplied by a scalar
182 181

	
183 182
  ///Return a vector multiplied by a scalar.
184 183
  ///\relates Point
185 184
  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
186 185
    return x*u;
187 186
  }
188 187

	
189
  ///Read a plainvector from a stream
188
  ///Read a plain vector from a stream
190 189

	
191
  ///Read a plainvector from a stream.
190
  ///Read a plain vector from a stream.
192 191
  ///\relates Point
193 192
  ///
194 193
  template<typename T>
195 194
  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
196 195
    char c;
197 196
    if (is >> c) {
198 197
      if (c != '(') is.putback(c);
199 198
    } else {
200 199
      is.clear();
201 200
    }
202 201
    if (!(is >> z.x)) return is;
203 202
    if (is >> c) {
... ...
@@ -205,27 +204,27 @@
205 204
    } else {
206 205
      is.clear();
207 206
    }
208 207
    if (!(is >> z.y)) return is;
209 208
    if (is >> c) {
210 209
      if (c != ')') is.putback(c);
211 210
    } else {
212 211
      is.clear();
213 212
    }
214 213
    return is;
215 214
  }
216 215

	
217
  ///Write a plainvector to a stream
216
  ///Write a plain vector to a stream
218 217

	
219
  ///Write a plainvector to a stream.
218
  ///Write a plain vector to a stream.
220 219
  ///\relates Point
221 220
  ///
222 221
  template<typename T>
223 222
  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
224 223
  {
225 224
    os << "(" << z.x << ", " << z.y << ")";
226 225
    return os;
227 226
  }
228 227

	
229 228
  ///Rotate by 90 degrees
230 229

	
231 230
  ///Returns the parameter rotated by 90 degrees in positive direction.
... ...
@@ -252,287 +251,290 @@
252 251

	
253 252
  ///Returns the parameter rotated by 90 degrees in negative direction.
254 253
  ///\relates Point
255 254
  ///
256 255
  template<typename T>
257 256
  inline Point<T> rot270(const Point<T> &z)
258 257
  {
259 258
    return Point<T>(z.y,-z.x);
260 259
  }
261 260

	
262 261

	
263 262

	
264
  /// A class to calculate or store the bounding box of plainvectors.
263
    /// A class to calculate or store the bounding box of plain vectors.
265 264

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

	
274 273
      ///Default constructor: creates an empty bounding box
275 274
      BoundingBox() { _empty = true; }
276 275

	
277 276
      ///Construct an instance from one point
278
      BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
277
      BoundingBox(Point<T> a) {
278
        _bottom_left = _top_right = a;
279
        _empty = false;
280
      }
279 281

	
280 282
      ///Construct an instance from two points
281 283

	
282 284
      ///Construct an instance from two points.
283 285
      ///\param a The bottom left corner.
284 286
      ///\param b The top right corner.
285 287
      ///\warning The coordinates of the bottom left corner must be no more
286 288
      ///than those of the top right one.
287 289
      BoundingBox(Point<T> a,Point<T> b)
288 290
      {
289
        bottom_left=a;
290
        top_right=b;
291
        _bottom_left = a;
292
        _top_right = b;
291 293
        _empty = false;
292 294
      }
293 295

	
294 296
      ///Construct an instance from four numbers
295 297

	
296 298
      ///Construct an instance from four numbers.
297 299
      ///\param l The left side of the box.
298 300
      ///\param b The bottom of the box.
299 301
      ///\param r The right side of the box.
300 302
      ///\param t The top of the box.
301 303
      ///\warning The left side must be no more than the right side and
302 304
      ///bottom must be no more than the top.
303 305
      BoundingBox(T l,T b,T r,T t)
304 306
      {
305
        bottom_left=Point<T>(l,b);
306
        top_right=Point<T>(r,t);
307
        _bottom_left=Point<T>(l,b);
308
        _top_right=Point<T>(r,t);
307 309
        _empty = false;
308 310
      }
309 311

	
310 312
      ///Return \c true if the bounding box is empty.
311 313

	
312 314
      ///Return \c true if the bounding box is empty (i.e. return \c false
313 315
      ///if at least one point was added to the box or the coordinates of
314 316
      ///the box were set).
315 317
      ///
316 318
      ///The coordinates of an empty bounding box are not defined.
317 319
      bool empty() const {
318 320
        return _empty;
319 321
      }
320 322

	
321 323
      ///Make the BoundingBox empty
322 324
      void clear() {
323
        _empty=1;
325
        _empty = true;
324 326
      }
325 327

	
326 328
      ///Give back the bottom left corner of the box
327 329

	
328 330
      ///Give back the bottom left corner of the box.
329 331
      ///If the bounding box is empty, then the return value is not defined.
330 332
      Point<T> bottomLeft() const {
331
        return bottom_left;
333
        return _bottom_left;
332 334
      }
333 335

	
334 336
      ///Set the bottom left corner of the box
335 337

	
336 338
      ///Set the bottom left corner of the box.
337
      ///It should only be used for non-empty box.
339
      ///\pre The box must not be empty.
338 340
      void bottomLeft(Point<T> p) {
339
        bottom_left = p;
341
        _bottom_left = p;
340 342
      }
341 343

	
342 344
      ///Give back the top right corner of the box
343 345

	
344 346
      ///Give back the top right corner of the box.
345 347
      ///If the bounding box is empty, then the return value is not defined.
346 348
      Point<T> topRight() const {
347
        return top_right;
349
        return _top_right;
348 350
      }
349 351

	
350 352
      ///Set the top right corner of the box
351 353

	
352 354
      ///Set the top right corner of the box.
353
      ///It should only be used for non-empty box.
355
      ///\pre The box must not be empty.
354 356
      void topRight(Point<T> p) {
355
        top_right = p;
357
        _top_right = p;
356 358
      }
357 359

	
358 360
      ///Give back the bottom right corner of the box
359 361

	
360 362
      ///Give back the bottom right corner of the box.
361 363
      ///If the bounding box is empty, then the return value is not defined.
362 364
      Point<T> bottomRight() const {
363
        return Point<T>(top_right.x,bottom_left.y);
365
        return Point<T>(_top_right.x,_bottom_left.y);
364 366
      }
365 367

	
366 368
      ///Set the bottom right corner of the box
367 369

	
368 370
      ///Set the bottom right corner of the box.
369
      ///It should only be used for non-empty box.
371
      ///\pre The box must not be empty.
370 372
      void bottomRight(Point<T> p) {
371
        top_right.x = p.x;
372
        bottom_left.y = p.y;
373
        _top_right.x = p.x;
374
        _bottom_left.y = p.y;
373 375
      }
374 376

	
375 377
      ///Give back the top left corner of the box
376 378

	
377 379
      ///Give back the top left corner of the box.
378 380
      ///If the bounding box is empty, then the return value is not defined.
379 381
      Point<T> topLeft() const {
380
        return Point<T>(bottom_left.x,top_right.y);
382
        return Point<T>(_bottom_left.x,_top_right.y);
381 383
      }
382 384

	
383 385
      ///Set the top left corner of the box
384 386

	
385 387
      ///Set the top left corner of the box.
386
      ///It should only be used for non-empty box.
388
      ///\pre The box must not be empty.
387 389
      void topLeft(Point<T> p) {
388
        top_right.y = p.y;
389
        bottom_left.x = p.x;
390
        _top_right.y = p.y;
391
        _bottom_left.x = p.x;
390 392
      }
391 393

	
392 394
      ///Give back the bottom of the box
393 395

	
394 396
      ///Give back the bottom of the box.
395 397
      ///If the bounding box is empty, then the return value is not defined.
396 398
      T bottom() const {
397
        return bottom_left.y;
399
        return _bottom_left.y;
398 400
      }
399 401

	
400 402
      ///Set the bottom of the box
401 403

	
402 404
      ///Set the bottom of the box.
403
      ///It should only be used for non-empty box.
405
      ///\pre The box must not be empty.
404 406
      void bottom(T t) {
405
        bottom_left.y = t;
407
        _bottom_left.y = t;
406 408
      }
407 409

	
408 410
      ///Give back the top of the box
409 411

	
410 412
      ///Give back the top of the box.
411 413
      ///If the bounding box is empty, then the return value is not defined.
412 414
      T top() const {
413
        return top_right.y;
415
        return _top_right.y;
414 416
      }
415 417

	
416 418
      ///Set the top of the box
417 419

	
418 420
      ///Set the top of the box.
419
      ///It should only be used for non-empty box.
421
      ///\pre The box must not be empty.
420 422
      void top(T t) {
421
        top_right.y = t;
423
        _top_right.y = t;
422 424
      }
423 425

	
424 426
      ///Give back the left side of the box
425 427

	
426 428
      ///Give back the left side of the box.
427 429
      ///If the bounding box is empty, then the return value is not defined.
428 430
      T left() const {
429
        return bottom_left.x;
431
        return _bottom_left.x;
430 432
      }
431 433

	
432 434
      ///Set the left side of the box
433 435

	
434 436
      ///Set the left side of the box.
435
      ///It should only be used for non-empty box.
437
      ///\pre The box must not be empty.
436 438
      void left(T t) {
437
        bottom_left.x = t;
439
        _bottom_left.x = t;
438 440
      }
439 441

	
440 442
      /// Give back the right side of the box
441 443

	
442 444
      /// Give back the right side of the box.
443 445
      ///If the bounding box is empty, then the return value is not defined.
444 446
      T right() const {
445
        return top_right.x;
447
        return _top_right.x;
446 448
      }
447 449

	
448 450
      ///Set the right side of the box
449 451

	
450 452
      ///Set the right side of the box.
451
      ///It should only be used for non-empty box.
453
      ///\pre The box must not be empty.
452 454
      void right(T t) {
453
        top_right.x = t;
455
        _top_right.x = t;
454 456
      }
455 457

	
456 458
      ///Give back the height of the box
457 459

	
458 460
      ///Give back the height of the box.
459 461
      ///If the bounding box is empty, then the return value is not defined.
460 462
      T height() const {
461
        return top_right.y-bottom_left.y;
463
        return _top_right.y-_bottom_left.y;
462 464
      }
463 465

	
464 466
      ///Give back the width of the box
465 467

	
466 468
      ///Give back the width of the box.
467 469
      ///If the bounding box is empty, then the return value is not defined.
468 470
      T width() const {
469
        return top_right.x-bottom_left.x;
471
        return _top_right.x-_bottom_left.x;
470 472
      }
471 473

	
472 474
      ///Checks whether a point is inside a bounding box
473 475
      bool inside(const Point<T>& u) const {
474 476
        if (_empty)
475 477
          return false;
476
        else{
477
          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
478
              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
478
        else {
479
          return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
480
                   (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
479 481
        }
480 482
      }
481 483

	
482 484
      ///Increments a bounding box with a point
483 485

	
484 486
      ///Increments a bounding box with a point.
485 487
      ///
486 488
      BoundingBox& add(const Point<T>& u){
487
        if (_empty){
488
          bottom_left=top_right=u;
489
        if (_empty) {
490
          _bottom_left = _top_right = u;
489 491
          _empty = false;
490 492
        }
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;
493
        else {
494
          if (_bottom_left.x > u.x) _bottom_left.x = u.x;
495
          if (_bottom_left.y > u.y) _bottom_left.y = u.y;
496
          if (_top_right.x < u.x) _top_right.x = u.x;
497
          if (_top_right.y < u.y) _top_right.y = u.y;
496 498
        }
497 499
        return *this;
498 500
      }
499 501

	
500 502
      ///Increments a bounding box to contain another bounding box
501 503

	
502 504
      ///Increments a bounding box to contain another bounding box.
503 505
      ///
504 506
      BoundingBox& add(const BoundingBox &u){
505 507
        if ( !u.empty() ){
506
          this->add(u.bottomLeft());
507
          this->add(u.topRight());
508
          add(u._bottom_left);
509
          add(u._top_right);
508 510
        }
509 511
        return *this;
510 512
      }
511 513

	
512 514
      ///Intersection of two bounding boxes
513 515

	
514 516
      ///Intersection of two bounding boxes.
515 517
      ///
516 518
      BoundingBox operator&(const BoundingBox& u) const {
517 519
        BoundingBox b;
518
        if (this->_empty || u._empty) {
520
        if (_empty || u._empty) {
519 521
          b._empty = true;
520 522
        } 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;
523
          b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
524
          b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
525
          b._top_right.x = std::min(_top_right.x, u._top_right.x);
526
          b._top_right.y = std::min(_top_right.y, u._top_right.y);
527
          b._empty = b._bottom_left.x > b._top_right.x ||
528
                     b._bottom_left.y > b._top_right.y;
527 529
        }
528 530
        return b;
529 531
      }
530 532

	
531 533
    };//class Boundingbox
532 534

	
533 535

	
534 536
  ///Map of x-coordinates of a \ref Point "Point"-map
535 537

	
536 538
  ///\ingroup maps
537 539
  ///Map of x-coordinates of a \ref Point "Point"-map.
538 540
  ///
0 comments (0 inline)