00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef LTI_RECTANGLE_H
00034 #define LTI_RECTANGLE_H
00035
00036 #include <iostream>
00037 #include "ltiIoHandler.h"
00038 #include "ltiConfig.h"
00039 #include "ltiPoint.h"
00040 #include "ltiMath.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049 namespace lti {
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template <class T>
00063 class rectSide {
00064 public:
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 static inline T size(const T x1,const T x2) {
00075 return (x2-x1+static_cast<T>(1));
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 static inline void invSize(const T sz,T& x1,T& x2) {
00088 x1=(static_cast<T>(1)-sz)/2;
00089 x2=x1+sz-1;
00090 }
00091 };
00092
00093
00094 template <>
00095 class rectSide<float> {
00096 public:
00097 static inline float size(const float x1,const float x2) {
00098 return (x2-x1);
00099 }
00100 static inline void invSize(const float sz,float& x1,float& x2) {
00101 x1=-sz/2.0f;
00102 x2=x1+sz;
00103 }
00104 };
00105
00106 template <>
00107 class rectSide<double> {
00108 public:
00109 static inline double size(const double& x1,const double& x2) {
00110 return (x2-x1);
00111 }
00112 static inline void invSize(const double sz,double& x1,double& x2) {
00113 x1=-sz/2.0;
00114 x2=x1+sz;
00115 }
00116 };
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 template <class T,class S=rectSide<T> >
00144 class trectangle {
00145 public:
00146
00147
00148
00149
00150 trectangle()
00151 : ul(tpoint<T>(0,0)),br(tpoint<T>(0,0)) {
00152 };
00153
00154
00155
00156
00157 trectangle(const tpoint<T>& p1,const tpoint<T>& p2)
00158 : ul(p1), br(p2) {
00159 };
00160
00161
00162
00163
00164 trectangle(const T& x1,const T& y1,
00165 const T& x2,const T& y2)
00166 : ul(tpoint<T>(x1,y1)),br(tpoint<T>(x2,y2)) {
00167 };
00168
00169
00170
00171
00172
00173
00174
00175
00176 trectangle(const T& size) {
00177 T low,high;
00178 S::invSize(size,low,high);
00179 ul.set(low,low);
00180 br.set(high,high);
00181 };
00182
00183
00184
00185
00186 trectangle(const trectangle<T>& other)
00187 : ul(other.ul),br(other.br) {
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 void resize(const tpoint<T>& dim) {
00199 tpoint<T> cen = getCenter();
00200 S::invSize(dim.x,ul.x,br.x);
00201 S::invSize(dim.y,ul.y,br.y);
00202 ul.add(cen);
00203 br.add(cen);
00204 };
00205
00206
00207
00208
00209 void resize(const T& x, const T& y) {
00210 tpoint<T> cen = getCenter();
00211 S::invSize(x,ul.x,br.x);
00212 S::invSize(y,ul.y,br.y);
00213 ul.add(cen);
00214 br.add(cen);
00215 };
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 tpoint<T> getDimensions() const {
00236 return tpoint<T>(S::size(ul.x,br.x),
00237 S::size(ul.y,br.y));
00238 };
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 T getArea() const {
00259 return abs(S::size(ul.x,br.x)*
00260 S::size(ul.y,br.y));
00261 };
00262
00263
00264
00265
00266 tpoint<T> getCenter() const {
00267 return tpoint<T>((br.x+ul.x)/2,(br.y+ul.y)/2);
00268 };
00269
00270
00271
00272
00273 void setCenter(tpoint<T> center) {
00274 tpoint<T> dim(abs(br.x-ul.x),abs(br.y-ul.y));
00275 ul.set(center.x - dim.x/2,center.y - dim.y/2);
00276 br.set(ul.x + dim.x,ul.y + dim.y);
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 void ensureConsistency() {
00286 trectangle<T> t(*this);
00287
00288 if (t.ul.x > t.br.x) {
00289 ul.x = t.br.x;
00290 br.x = t.ul.x;
00291 }
00292
00293 if (t.ul.y > t.br.y) {
00294 ul.y = t.br.y;
00295 br.y = t.ul.y;
00296 }
00297 };
00298
00299
00300
00301
00302
00303 bool isConsistent() const {
00304 return !((ul.x > br.x) || (ul.y > br.y));
00305 };
00306
00307
00308
00309
00310 void shift(const tpoint<T>& delta) {
00311 ul.add(delta);
00312 br.add(delta);
00313 };
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 bool isInside(const tpoint<T>& p) const {
00326 return ((p.x>=ul.x) && (p.x<=br.x) &&
00327 (p.y>=ul.y) && (p.y<=br.y));
00328 };
00329
00330
00331
00332
00333
00334 bool isInside(const T& x, const T& y) const {
00335 return ((x>=ul.x) && (x<=br.x) &&
00336 (y>=ul.y) && (y<=br.y));
00337 };
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 trectangle<T>& copy(const trectangle<T>& other) {
00351 ul.copy(other.ul);
00352 br.copy(other.br);
00353 return (*this);
00354 };
00355
00356
00357
00358
00359 template <class U,class SU>
00360 trectangle<T>& castFrom(const trectangle<U,SU>& other) {
00361 ul.x = static_cast<T>(other.ul.x);
00362 ul.y = static_cast<T>(other.ul.y);
00363 br.x = static_cast<T>(other.br.x);
00364 br.y = static_cast<T>(other.br.y);
00365
00366 return (*this);
00367 };
00368
00369
00370
00371
00372 trectangle<T>& operator=(const trectangle<T>& other) {
00373 return (copy(other));
00374 };
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 bool operator==(const trectangle<T>& other) const {
00387 return ((other.ul == ul) &&
00388 (other.br == br));
00389 };
00390
00391
00392
00393
00394 bool operator!=(const trectangle<T>& other) const {
00395 return ((other.ul != ul) ||
00396 (other.br != br));
00397 };
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 trectangle<T>& intersectRect(const trectangle<T>& tRect) {
00411 return intersect(tRect);
00412 };
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 trectangle<T>& intersect(const trectangle<T>& tRect) {
00428 if (tRect.ul.x > ul.x) {
00429 ul.x = tRect.ul.x;
00430 }
00431 if (tRect.ul.y > ul.y) {
00432 ul.y = tRect.ul.y;
00433 }
00434 if (tRect.br.x < br.x) {
00435 br.x = tRect.br.x;
00436 }
00437 if (tRect.br.y < br.y) {
00438 br.y = tRect.br.y;
00439 }
00440 return (*this);
00441 };
00442
00443
00444
00445
00446
00447 bool overlaps(const trectangle<T>& tRect) const {
00448 trectangle<T> rect(*this);
00449 rect.intersect(tRect);
00450 return rect.isConsistent();
00451 };
00452
00453
00454
00455
00456
00457 bool isClose(const trectangle<T>& tRect, const tpoint<T>& dist) const {
00458 const tpoint<T> br1 ( tRect.br + dist );
00459 const tpoint<T> ul1 ( tRect.ul - dist );
00460
00461 if ( br.x >= ul1.x ) {
00462 if ( br.x <= br1.x ) {
00463 if ( br.y >= ul1.y ) {
00464 if ( br.y <= br1.y ) {
00465 return true;
00466
00467 } else if ( ul.y <= br1.y ) {
00468 return true;
00469
00470 } else {
00471 return false;
00472 }
00473
00474 } else {
00475 return false;
00476 }
00477
00478 } else if ( ul.x <= br1.x ) {
00479 if ( ul.y >= ul1.y ) {
00480 if ( ul.y <= br1.y ) {
00481 return true;
00482
00483 } else {
00484 return false;
00485 }
00486
00487 } else if ( br.y >= ul1.y ) {
00488 if ( ul.y <= br1.y ) {
00489 return true;
00490
00491 } else {
00492 return false;
00493 }
00494
00495 } else {
00496 return false;
00497 }
00498 }
00499 }
00500
00501 return false;
00502 };
00503
00504
00505
00506
00507
00508
00509 trectangle<T>& operator&=(const trectangle<T>& tRect) {
00510 return intersect(tRect);
00511 };
00512
00513
00514
00515
00516 trectangle<T> operator&(const trectangle<T>& tRect) {
00517 trectangle<T> tempRect(*this);
00518 return tempRect.intersect(tRect);
00519 };
00520
00521
00522
00523
00524
00525 trectangle<T>& unionRect(const trectangle<T>& tRect) {
00526 return join(tRect);
00527 }
00528
00529
00530
00531
00532
00533
00534
00535 trectangle<T>& join(const trectangle<T>& tRect) {
00536 if (tRect.ul.x < ul.x) {
00537 ul.x = tRect.ul.x;
00538 }
00539 if (tRect.ul.y < ul.y) {
00540 ul.y = tRect.ul.y;
00541 }
00542 if (tRect.br.x > br.x) {
00543 br.x = tRect.br.x;
00544 }
00545 if (tRect.br.y > br.y) {
00546 br.y = tRect.br.y;
00547 }
00548 return (*this);
00549 };
00550
00551
00552
00553
00554
00555 trectangle<T>& operator|=(const trectangle<T>& tRect) {
00556 return join(tRect);
00557 };
00558
00559
00560
00561
00562 trectangle<T> operator|(const trectangle<T>& tRect) {
00563 trectangle<T> tempRect(*this);
00564 return tempRect.join(tRect);
00565 };
00566
00567
00568
00569
00570
00571
00572
00573 tpoint<T> ul;
00574
00575
00576
00577
00578 tpoint<T> br;
00579
00580 };
00581
00582
00583
00584
00585
00586
00587 typedef trectangle<int> rectangle;
00588
00589
00590
00591
00592
00593
00594 typedef trectangle<int> irectangle;
00595
00596
00597
00598
00599
00600
00601 typedef trectangle<float> frectangle;
00602
00603
00604
00605
00606
00607
00608 typedef trectangle<double> drectangle;
00609
00610
00611
00612
00613
00614
00615
00616 template<class T,class S>
00617 bool read(ioHandler& handler,trectangle<T,S>& p,const bool complete=true) {
00618 bool b;
00619
00620 if (complete) {
00621 handler.readBegin();
00622 }
00623
00624 read(handler,p.ul);
00625 handler.readDataSeparator();
00626 b = read(handler,p.br);
00627
00628 if (complete) {
00629 b = handler.readEnd();
00630 }
00631
00632 return b;
00633 };
00634
00635
00636
00637
00638
00639
00640
00641 template <class T,class S>
00642 bool write(ioHandler& handler,const trectangle<T,S>& p,
00643 const bool complete=true) {
00644 bool b;
00645
00646 if (complete) {
00647 handler.writeBegin();
00648 }
00649 write(handler,p.ul);
00650 handler.writeDataSeparator();
00651 b = write(handler,p.br);
00652
00653 if (complete) {
00654 b = handler.writeEnd();
00655 }
00656
00657 return b;
00658 };
00659 }
00660
00661 namespace std {
00662
00663
00664 template <class T,class S>
00665 inline ostream& operator<<(ostream& s,const lti::trectangle<T,S>& p) {
00666 s << "(" << p.ul << ","
00667 << p.br << ")";
00668 return s;
00669 };
00670
00671
00672 template <class T,class S>
00673 inline istream& operator>>(istream& s,lti::trectangle<T,S>& p) {
00674 char c;
00675 lti::tpoint<T> ul,br;
00676 s >> c
00677 >> ul >> c
00678 >> br >> c;
00679 p.ul = ul;
00680 p.br = br;
00681
00682 return s;
00683 };
00684 }
00685
00686 #endif