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_BOX_H
00034 #define LTI_BOX_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 boxSide {
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 boxSide<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 boxSide<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 template <class T,class S=boxSide<T> >
00125 class tbox {
00126 public:
00127
00128
00129
00130 tbox()
00131 : min(tpoint3D<T>(0,0,0)),max(tpoint3D<T>(0,0,0)) {
00132 };
00133
00134
00135
00136
00137 tbox(const tpoint3D<T>& p1,const tpoint3D<T>& p2)
00138 : min(p1), max(p2) {
00139 };
00140
00141
00142
00143
00144 tbox(const T& x1,const T& y1,const T& z1,
00145 const T& x2,const T& y2,const T& z2)
00146 : min(tpoint3D<T>(x1,y1,z1)),max(tpoint3D<T>(x2,y2,z2)) {
00147 };
00148
00149
00150
00151
00152
00153
00154
00155
00156 tbox(const T& size) {
00157 T low,high;
00158 S::invSize(size,low,high);
00159 min.set(low,low,low);
00160 max.set(high,high,high);
00161 };
00162
00163
00164
00165
00166 tbox(const tbox<T>& other)
00167 : min(other.min),max(other.max) {
00168 };
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 void resize(const tpoint3D<T>& dim) {
00179 tpoint3D<T> cen = getCenter();
00180 S::invSize(dim.x,min.x,max.x);
00181 S::invSize(dim.y,min.y,max.y);
00182 S::invSize(dim.z,min.z,max.z);
00183 min.add(cen);
00184 max.add(cen);
00185 };
00186
00187
00188
00189
00190 void resize(const T& x, const T& y, const T& z) {
00191 tpoint3D<T> cen = getCenter();
00192
00193 S::invSize(x,min.x,max.x);
00194 S::invSize(y,min.y,max.y);
00195 S::invSize(z,min.z,max.z);
00196
00197 min.add(cen);
00198 max.add(cen);
00199 };
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 tpoint3D<T> getDimensions() const {
00220 return tpoint3D<T>(S::size(min.x,max.x),
00221 S::size(min.y,max.y),
00222 S::size(min.z,max.z));
00223 };
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 T getVolume() const {
00244 return abs(S::size(min.x,max.x)*
00245 S::size(min.y,max.y)*
00246 S::size(min.z,max.z));
00247 };
00248
00249
00250
00251
00252 tpoint3D<T> getCenter() const {
00253 return tpoint3D<T>((max.x+min.x)/2,(max.y+min.y)/2,(max.z+min.z)/2);
00254 };
00255
00256
00257
00258
00259 void setCenter(tpoint3D<T> center) {
00260 tpoint3D<T> dim(abs(max.x-min.x),abs(max.y-min.y),abs(max.z-min.z));
00261 min.set(center.x - dim.x/2,center.y - dim.y/2,center.z - dim.z/2);
00262 max.set(min.x + dim.x, min.y + dim.y, min.z + dim.z);
00263 }
00264
00265
00266
00267
00268
00269
00270 void ensureConsistency() {
00271 tbox<T> t(*this);
00272
00273 if (t.min.x > t.max.x) {
00274 min.x = t.max.x;
00275 max.x = t.min.x;
00276 }
00277
00278 if (t.min.y > t.max.y) {
00279 min.y = t.max.y;
00280 max.y = t.min.y;
00281 }
00282
00283 if (t.min.z > t.max.z) {
00284 min.z = t.max.z;
00285 max.z = t.min.z;
00286 }
00287 };
00288
00289
00290
00291
00292
00293 bool isConsistent() const {
00294 return !( (min.x > max.x) || (min.y > max.y) || (min.z > max.z) );
00295 };
00296
00297
00298
00299
00300 void shift(const tpoint3D<T>& delta) {
00301 min.add(delta);
00302 max.add(delta);
00303 };
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 bool isInside(const tpoint3D<T>& p) const {
00315 return ( (p.x>=min.x) && (p.x<=max.x) &&
00316 (p.y>=min.y) && (p.y<=max.y) &&
00317 (p.z>=min.z) && (p.z<=max.z) );
00318 };
00319
00320
00321
00322
00323
00324 bool isInside(const T& x, const T& y, const T& z) const {
00325 return ( (x>=min.x) && (x<=max.x) &&
00326 (y>=min.y) && (y<=max.y) &&
00327 (z>=min.z) && (z<=max.z) );
00328 };
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 tbox<T>& copy(const tbox<T>& other) {
00342 min.copy(other.min);
00343 max.copy(other.max);
00344 return (*this);
00345 };
00346
00347
00348
00349
00350 template <class U,class SU>
00351 tbox<T>& castFrom(const tbox<U,SU>& other) {
00352
00353 min.castFrom(other.min);
00354 max.castFrom(other.max);
00355
00356 return (*this);
00357 };
00358
00359
00360
00361
00362 tbox<T>& operator=(const tbox<T>& other) {
00363 return (copy(other));
00364 };
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 bool operator==(const tbox<T>& other) const {
00377 return ( (other.min == min) &&
00378 (other.max == max) );
00379 };
00380
00381
00382
00383
00384 bool operator!=(const tbox<T>& other) const {
00385 return ( (other.min != min) ||
00386 (other.max != max) );
00387 };
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 tbox<T>& intersect(const tbox<T>& tRect) {
00410 if (tRect.min.x > min.x) {
00411 min.x = tRect.min.x;
00412 }
00413 if (tRect.min.y > min.y) {
00414 min.y = tRect.min.y;
00415 }
00416 if (tRect.min.z > min.z) {
00417 min.z = tRect.min.z;
00418 }
00419
00420 if (tRect.max.x < max.x) {
00421 max.x = tRect.max.x;
00422 }
00423 if (tRect.max.y < max.y) {
00424 max.y = tRect.max.y;
00425 }
00426 if (tRect.max.z < max.z) {
00427 max.z = tRect.max.z;
00428 }
00429 return (*this);
00430 };
00431
00432
00433
00434
00435
00436 bool overlaps(const tbox<T>& tRect) const {
00437 tbox<T> rect(*this);
00438 rect.intersect(tRect);
00439 return rect.isConsistent();
00440 };
00441
00442
00443
00444
00445
00446 tbox<T>& operator&=(const tbox<T>& tRect) {
00447 return intersect(tRect);
00448 };
00449
00450
00451
00452
00453 tbox<T> operator&(const tbox<T>& tRect) {
00454 tbox<T> tempRect(*this);
00455 return tempRect.intersect(tRect);
00456 };
00457
00458
00459
00460
00461
00462
00463
00464 tbox<T>& join(const tbox<T>& tRect) {
00465 if (tRect.min.x < min.x) {
00466 min.x = tRect.min.x;
00467 }
00468 if (tRect.min.y < min.y) {
00469 min.y = tRect.min.y;
00470 }
00471 if (tRect.min.z < min.z) {
00472 min.z = tRect.min.z;
00473 }
00474
00475 if (tRect.max.x > max.x) {
00476 max.x = tRect.max.x;
00477 }
00478 if (tRect.max.y > max.y) {
00479 max.y = tRect.max.y;
00480 }
00481 if (tRect.max.z > max.z) {
00482 max.z = tRect.max.z;
00483 }
00484 return (*this);
00485 };
00486
00487
00488
00489
00490
00491 tbox<T>& operator|=(const tbox<T>& tRect) {
00492 return join(tRect);
00493 };
00494
00495
00496
00497
00498 tbox<T> operator|(const tbox<T>& tRect) {
00499 tbox<T> tempRect(*this);
00500 return tempRect.join(tRect);
00501 };
00502
00503
00504
00505
00506
00507
00508 tpoint3D<T> min;
00509
00510
00511
00512
00513 tpoint3D<T> max;
00514
00515 };
00516
00517
00518
00519
00520 typedef tbox<int> box;
00521
00522
00523
00524
00525
00526
00527
00528 template<class T,class S>
00529 bool read(ioHandler& handler,tbox<T,S>& p,const bool complete=true) {
00530 bool b;
00531
00532 if (complete) {
00533 handler.readBegin();
00534 }
00535
00536 read(handler,p.min);
00537 handler.readDataSeparator();
00538 b = read(handler,p.max);
00539
00540 if (complete) {
00541 b = handler.readEnd();
00542 }
00543
00544 return b;
00545 };
00546
00547
00548
00549
00550
00551
00552
00553 template <class T,class S>
00554 bool write(ioHandler& handler,const tbox<T,S>& p,
00555 const bool complete=true) {
00556 bool b;
00557
00558 if (complete) {
00559 handler.writeBegin();
00560 }
00561 write(handler,p.min);
00562 handler.writeDataSeparator();
00563 b = write(handler,p.max);
00564
00565 if (complete) {
00566 b = handler.writeEnd();
00567 }
00568
00569 return b;
00570 };
00571 }
00572
00573 namespace std {
00574
00575
00576 template <class T,class S>
00577 inline ostream& operator<<(ostream& s,const lti::tbox<T,S>& p) {
00578 s << "(" << p.min << ","
00579 << p.max << ")";
00580 return s;
00581 };
00582
00583
00584 template <class T,class S>
00585 inline istream& operator>>(istream& s,lti::tbox<T,S>& p) {
00586 char c;
00587 lti::tpoint3D<T> min,max;
00588 s >> c
00589 >> min >> c
00590 >> max >> c;
00591 p.min = min;
00592 p.max = max;
00593
00594 return s;
00595 };
00596 }
00597
00598 #endif