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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
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 #ifndef INC_MI32_RECT_H
00144 #define INC_MI32_RECT_H
00145
00146
00147
00148
00149
00150
00151
00152 #ifndef INC_MI32_STDDEFNS_H
00153 #include <mi32/stddefns.h>
00154 #endif
00155
00156 #ifndef INC_MI32_INIDEFNS_H
00157 #include <mi32/inidefns.h>
00158 #endif
00159
00160 #ifdef ALLOW_NAMESPACES
00161 #include <limits>
00162 #include <cmath>
00163 #else
00164 #include <limits.h>
00165 #include <math.h>
00166 #include <float.h>
00167 #endif
00168
00169 #ifndef INC_MI32_POINT_H
00170 #include <mi32/point.h>
00171 #endif
00172
00173 #ifndef GENERATING_DOXYGEN_OUTPUT
00174
00175 #ifdef GEOMDLL
00176 #define GEOMLIBEXPORT MI_DLLEXPORT
00177 #define GEOMLIBCLASSEXPORT MI_DLLCLASSEXPORT
00178 #else
00179 #define GEOMLIBEXPORT MI_DLLIMPORT
00180 #define GEOMLIBCLASSEXPORT MI_DLLCLASSIMPORT
00181 #endif
00182
00183 GEOMLIBEXPORT void LRect2DGetCorners (const LRECT2D& rect, LPOINT2D *pts, bool ClosePoly, bool OrientCCW);
00184 GEOMLIBEXPORT bool DRect2DComputeEdgePoint (const DRECT2D& rect, const DPOINT2D& OutsidePt, DPOINT2D& EdgePt);
00185 GEOMLIBEXPORT void DRect2DGetCorners (const DRECT2D& rect, DPOINT2D *pts, bool ClosePoly, bool OrientCCW);
00186 GEOMLIBEXPORT void DRect2DGetCorners (const DRECT2D& rect, DPOINT3D *pts, bool ClosePoly, bool OrientCCW);
00187 GEOMLIBEXPORT double DRect2DGetDistance (const DRECT2D& trect, const DRECT2D& rect);
00188 GEOMLIBEXPORT double DRect2DGetMaxDistance (const DRECT2D& trect, const DRECT2D& rect);
00189 GEOMLIBEXPORT double DRect2DGetMaxDistanceSquared (const DRECT2D& trect, const DRECT2D& rect);
00190 GEOMLIBEXPORT bool DRect2DIsEquivalentTo (const DRECT2D& trect, const DRECT2D& rect, double thresold);
00191
00192 #endif //GENERATING_DOXYGEN_OUTPUT
00193
00194
00195
00196
00197 struct WRECT2D {
00198 INT16 xinit;
00199 INT16 yinit;
00200 INT16 xlast;
00201 INT16 ylast;
00202
00203
00204 CHECKSIZE(8);
00205 };
00206
00207
00208
00209
00210 struct LRECT2D {
00211
00212 INT32 xinit;
00213 INT32 yinit;
00214 INT32 xlast;
00215 INT32 ylast;
00216
00217
00218 LRECT2D (
00219 ): xinit(INT32_MAX), yinit(INT32_MAX), xlast(INT32_MIN), ylast(INT32_MIN) { }
00220
00221
00222 LRECT2D (
00223 INT32 xsize,
00224 INT32 ysize
00225 ) : xinit(0), yinit(0), xlast(xsize-1), ylast(ysize-1) { }
00226
00227
00228 LRECT2D (
00229 INT32 xi,
00230 INT32 yi,
00231 INT32 xl,
00232 INT32 yl
00233 ) : xinit(xi), yinit(yi), xlast(xl), ylast(yl) { }
00234
00235
00236 bool Contains (
00237 INT32 x,
00238 INT32 y
00239 ) const { return (x >= xinit && x <= xlast && y >= yinit && y <= ylast); }
00240
00241
00242 bool Contains (
00243 const LPOINT2D& pt
00244 ) const { return (pt.x >= xinit && pt.x <= xlast && pt.y >= yinit && pt.y <= ylast); }
00245
00246
00247 bool Contains (
00248 const LRECT2D& rhs
00249 ) const { return (rhs.xinit >= xinit && rhs.xlast <= xlast && rhs.yinit >= yinit && rhs.ylast <= ylast); }
00250
00251
00252 void Expand (
00253 const INT32 value
00254 ) { xinit -= value; yinit -= value; xlast += value; ylast += value; }
00255
00256
00257 void Expand (
00258 const INT32 xval,
00259 const INT32 yval
00260 ) { xinit -= xval; yinit -= yval; xlast += xval; ylast += yval; }
00261
00262
00263 void Extend (
00264 const LRECT2D& rect
00265 ) {
00266 if (rect.xinit < xinit) xinit = rect.xinit;
00267 if (rect.yinit < yinit) yinit = rect.yinit;
00268 if (rect.xlast > xlast) xlast = rect.xlast;
00269 if (rect.ylast > ylast) ylast = rect.ylast;
00270 }
00271
00272
00273 void Extend (
00274 const LPOINT2D& pt
00275 ) {
00276 if (pt.x < xinit) xinit = pt.x;
00277 if (pt.x > xlast) xlast = pt.x;
00278 if (pt.y < yinit) yinit = pt.y;
00279 if (pt.y > ylast) ylast = pt.y;
00280 }
00281
00282
00283 void Extend (
00284 const INT32 xval,
00285 const INT32 yval
00286 ) {
00287 if (xval < xinit) xinit = xval;
00288 if (yval < yinit) yinit = yval;
00289 if (xval > xlast) xlast = xval;
00290 if (yval > ylast) ylast = yval;
00291 }
00292
00293
00294 INT32 GetArea (
00295 ) const { return (GetWidth() * GetHeight()); }
00296
00297
00298 void GetBottomLeft (
00299 LPOINT2D& ret
00300 ) const { ret.x = xinit; ret.y = yinit; }
00301
00302
00303 void GetBottomRight (
00304 LPOINT2D& ret
00305 ) const { ret.x = xlast; ret.y = yinit; }
00306
00307
00308 DPOINT2D GetCenter (
00309 ) const { return (DPOINT2D((xlast + xinit)/2.0, (ylast + yinit)/2.0)); }
00310
00311
00312 void GetCenter (
00313 DPOINT2D& ret
00314 ) const { ret.x = (xinit + xlast) / 2.0; ret.y = (yinit + ylast) / 2.0; }
00315
00316
00317 void GetCorners (
00318 LPOINT2D *corners,
00319 bool ClosePoly = false,
00320 bool OrientCCW = false
00321 ) const { LRect2DGetCorners(*this, corners, ClosePoly, OrientCCW); }
00322
00323
00324 int GetDimension (
00325 ) const {
00326 int count(0);
00327 if (xinit < xlast) count ++;
00328 if (yinit < ylast) count ++;
00329 return (count);
00330 }
00331
00332
00333 UINT32 GetHeight (
00334 ) const { return (ylast - yinit + 1); }
00335
00336
00337 void GetSize (
00338 LPOINT2D& ret
00339 ) const { ret.x = xlast - xinit; ret.y = ylast - yinit; }
00340
00341
00342 void GetTopLeft (
00343 LPOINT2D& ret
00344 ) const { ret.x = xinit; ret.y = ylast; }
00345
00346
00347 void GetTopRight (
00348 LPOINT2D& ret
00349 ) const { ret.x = xlast; ret.y = ylast; }
00350
00351
00352 UINT32 GetWidth (
00353 ) const { return (xlast - xinit + 1); }
00354
00355
00356 bool IniRead (
00357 INIHANDLE IniHandle,
00358 const char *IniGroup,
00359 const char *IniName
00360 ) { return (_iniRead(IniHandle,IniGroup,IniName,INITYPE_INT32,this,4) == 4); }
00361
00362
00363 void IniWrite (
00364 INIHANDLE IniHandle,
00365 const char *IniGroup,
00366 const char *IniName
00367 ) const { _iniWrite(IniHandle,IniGroup,IniName,INITYPE_INT32,this,4); }
00368
00369
00370 void Intersect (
00371 const LRECT2D& rect
00372 ) {
00373 if (rect.IsValid()) {
00374 if (rect.xinit > xinit) xinit = rect.xinit;
00375 if (rect.yinit > yinit) yinit = rect.yinit;
00376 if (rect.xlast < xlast) xlast = rect.xlast;
00377 if (rect.ylast < ylast) ylast = rect.ylast;
00378 }
00379 else {
00380 *this = rect;
00381 }
00382 return;
00383 }
00384
00385
00386 bool IsValid (
00387 ) const { return (xinit <= xlast && yinit <= ylast); }
00388
00389
00390 void Limit (
00391 LPOINT2D& point
00392 ) const {
00393 if (point.x < xinit) point.x = xinit; else if (point.x > xlast) point.x = xlast;
00394 if (point.y < yinit) point.y = yinit; else if (point.y > ylast) point.y = ylast;
00395 }
00396
00397
00398 void Limit (
00399 DPOINT2D& point
00400 ) const {
00401 if (point.x < xinit) point.x = xinit; else if (point.x > xlast) point.x = xlast;
00402 if (point.y < yinit) point.y = yinit; else if (point.y > ylast) point.y = ylast;
00403 }
00404
00405
00406 bool Overlaps (
00407 const LRECT2D& rhs
00408 ) const {
00409 return (!(rhs.xlast < xinit || rhs.xinit > xlast || rhs.ylast < yinit || rhs.yinit > ylast));
00410 }
00411
00412
00413 void Set (
00414 INT32 x1,
00415 INT32 y1,
00416 INT32 x2,
00417 INT32 y2
00418 ) { xinit = x1; yinit = y1; xlast = x2; ylast = y2; }
00419
00420
00421
00422
00423
00424 void SetInvalid (
00425 ) { xinit = yinit = INT32_MAX; xlast = ylast = INT32_MIN; }
00426
00427
00428 void SwapBytes (
00429 ) { ::SwapBytes(xinit); ::SwapBytes(xlast); ::SwapBytes(yinit); ::SwapBytes(ylast); }
00430
00431
00432 CHECKSIZE(16);
00433 };
00434
00435 inline bool operator== (
00436 const LRECT2D& lhs,
00437 const LRECT2D& rhs
00438 ) {
00439 return (lhs.xinit == rhs.xinit && lhs.xlast == rhs.xlast && lhs.yinit == rhs.yinit && lhs.ylast == rhs.ylast);
00440 }
00441
00442 inline bool operator!= (
00443 const LRECT2D& lhs,
00444 const LRECT2D& rhs
00445 ) {
00446 return (!operator==(lhs,rhs));
00447 }
00448
00449
00450
00451
00452
00453 struct DRECT2D {
00454
00455 double xinit;
00456 double yinit;
00457 double xlast;
00458 double ylast;
00459
00460
00461 DRECT2D (
00462 ) : xinit(DBL_MAX), yinit(DBL_MAX), xlast(-DBL_MAX), ylast(-DBL_MAX) {
00463 }
00464
00465
00466 DRECT2D (
00467 const FPOINT2D& pt
00468 ) : xinit(pt.x), yinit(pt.y), xlast(pt.x), ylast(pt.y) { }
00469
00470
00471 DRECT2D (
00472 const DPOINT2D& pt
00473 ) : xinit(pt.x), yinit(pt.y), xlast(pt.x), ylast(pt.y) { }
00474
00475
00476
00477
00478 DRECT2D (
00479 const DPOINT2D& pt1,
00480 const DPOINT2D& pt2
00481 ) {
00482 if (pt1.x < pt2.x) {
00483 xinit = pt1.x;
00484 xlast = pt2.x;
00485 }
00486 else {
00487 xinit = pt2.x;
00488 xlast = pt1.x;
00489 }
00490 if (pt1.y < pt2.y) {
00491 yinit = pt1.y;
00492 ylast = pt2.y;
00493 }
00494 else {
00495 yinit = pt2.y;
00496 ylast = pt1.y;
00497 }
00498 }
00499
00500 DRECT2D (
00501 double xi,
00502 double yi,
00503 double xl,
00504 double yl
00505 ) : xinit(xi), yinit(yi), xlast(xl), ylast(yl) { }
00506
00507
00508 DRECT2D (
00509 const LRECT2D& rect
00510 ) : xinit(rect.xinit), yinit(rect.yinit), xlast(rect.xlast), ylast(rect.ylast) { }
00511
00512
00513 DRECT2D& operator= (
00514 const DPOINT2D& pt
00515 ) { xinit = xlast = pt.x; yinit = ylast = pt.y; return (*this); }
00516
00517
00518 DRECT2D& operator= (
00519 const LRECT2D& rhs
00520 ) { xinit = rhs.xinit; yinit = rhs.yinit; xlast = rhs.xlast; ylast = rhs.ylast; return (*this); }
00521
00522
00523 void ClipTo (
00524 const DRECT2D& rect
00525 ) {
00526 if (xinit < rect.xinit) xinit = rect.xinit;
00527 if (yinit < rect.yinit) yinit = rect.yinit;
00528 if (xlast > rect.xlast) xlast = rect.xlast;
00529 if (ylast > rect.ylast) ylast = rect.ylast;
00530 return;
00531 }
00532
00533
00534
00535
00536
00537 bool ComputeEdgePoint (
00538 const DPOINT2D& OutsidePt,
00539 DPOINT2D& EdgePt
00540 ) const { return (DRect2DComputeEdgePoint(*this, OutsidePt, EdgePt)); }
00541
00542
00543 bool Contains (
00544 double x,
00545 double y
00546 ) const { return (x >= xinit && x <= xlast && y >= yinit && y <= ylast); }
00547
00548
00549 bool Contains (
00550 const DPOINT2D& pt
00551 ) const { return (pt.x >= xinit && pt.x <= xlast && pt.y >= yinit && pt.y <= ylast); }
00552
00553
00554 bool Contains (
00555 const DRECT2D& rhs
00556 ) const { return (rhs.xinit >= xinit && rhs.xlast <= xlast && rhs.yinit >= yinit && rhs.ylast <= ylast); }
00557
00558
00559 void Expand (
00560 const double value
00561 ) { xinit -= value; yinit -= value; xlast += value; ylast += value; }
00562
00563
00564 void Expand (
00565 const double xval,
00566 const double yval
00567 ) { xinit -= xval; yinit -= yval; xlast += xval; ylast += yval; }
00568
00569
00570 void Extend (
00571 const double xval,
00572 const double yval
00573 ) {
00574 if (xval < xinit) xinit = xval;
00575 if (yval < yinit) yinit = yval;
00576 if (xval > xlast) xlast = xval;
00577 if (yval > ylast) ylast = yval;
00578 return;
00579 }
00580
00581
00582 void Extend (
00583 const DRECT2D& rect
00584 ) {
00585 if (rect.xinit < xinit) xinit = rect.xinit;
00586 if (rect.yinit < yinit) yinit = rect.yinit;
00587 if (rect.xlast > xlast) xlast = rect.xlast;
00588 if (rect.ylast > ylast) ylast = rect.ylast;
00589 return;
00590 }
00591
00592
00593 void Extend (
00594 const DPOINT2D& pt
00595 ) {
00596 if (pt.x < xinit) xinit = pt.x;
00597 if (pt.x > xlast) xlast = pt.x;
00598 if (pt.y < yinit) yinit = pt.y;
00599 if (pt.y > ylast) ylast = pt.y;
00600 return;
00601 }
00602
00603
00604 double GetArea (
00605 ) const { return ((xlast - xinit) * (ylast - yinit)); }
00606
00607
00608 void GetBottomLeft (
00609 DPOINT2D& ret
00610 ) const { ret.x = xinit; ret.y = yinit; }
00611
00612
00613 void GetBottomRight (
00614 DPOINT2D& ret
00615 ) const { ret.x = xlast; ret.y = yinit; }
00616
00617
00618 DPOINT2D GetCenter (
00619 ) const { return (DPOINT2D((xlast + xinit)/2.0, (ylast + yinit)/2.0)); }
00620
00621
00622 void GetCenter (
00623 DPOINT2D& ret
00624 ) const { ret.x = (xinit + xlast) / 2.0; ret.y = (yinit + ylast) / 2.0; }
00625
00626
00627 void GetCorners (
00628 DPOINT2D *corners,
00629 bool ClosePoly = false,
00630 bool OrientCCW = false
00631 ) const { DRect2DGetCorners(*this, corners, ClosePoly, OrientCCW); }
00632
00633
00634 void GetCorners (
00635 DPOINT3D *corners,
00636 bool ClosePoly = false,
00637 bool OrientCCW = false
00638 ) const { DRect2DGetCorners(*this, corners, ClosePoly, OrientCCW); }
00639
00640
00641 int GetDimension (
00642 ) const {
00643 int count(0);
00644 if (xinit < xlast) count ++;
00645 if (yinit < ylast) count ++;
00646 return (count);
00647 }
00648
00649
00650
00651 double GetDistance (
00652 const DRECT2D& rect
00653 ) const { return (DRect2DGetDistance(*this, rect)); }
00654
00655
00656 double GetHeight (
00657 ) const { return (ylast - yinit); }
00658
00659
00660
00661
00662 double GetMaxDistance (
00663 const DRECT2D& rect
00664 ) const { return (DRect2DGetMaxDistance(*this, rect)); }
00665
00666
00667
00668
00669 double GetMaxDistanceSquared (
00670 const DRECT2D& rect
00671 ) const { return (DRect2DGetMaxDistanceSquared(*this, rect)); }
00672
00673
00674 void GetRect (
00675 LRECT2D& rect
00676 ) const {
00677 rect.xinit = static_cast<INT32>(FAST_ROUND(xinit));
00678 rect.yinit = static_cast<INT32>(FAST_ROUND(yinit));
00679 rect.xlast = static_cast<INT32>(FAST_ROUND(xlast));
00680 rect.ylast = static_cast<INT32>(FAST_ROUND(ylast));
00681 return;
00682 }
00683
00684
00685 void GetRectTruncate (
00686 LRECT2D& rect
00687 ) const {
00688 rect.xinit = static_cast<INT32>(FAST_TRUNCATE(xinit));
00689 rect.yinit = static_cast<INT32>(FAST_TRUNCATE(yinit));
00690 rect.xlast = static_cast<INT32>(FAST_TRUNCATE(xlast));
00691 rect.ylast = static_cast<INT32>(FAST_TRUNCATE(ylast));
00692 return;
00693 }
00694
00695
00696 void GetSize (
00697 DPOINT2D& ret
00698 ) const { ret.x = xlast - xinit; ret.y = ylast - yinit; }
00699
00700
00701 void GetTopLeft (
00702 DPOINT2D& ret
00703 ) const { ret.x = xinit; ret.y = ylast; }
00704
00705
00706 void GetTopRight (
00707 DPOINT2D& ret
00708 ) const { ret.x = xlast; ret.y = ylast; }
00709
00710
00711 double GetWidth (
00712 ) const { return (xlast - xinit); }
00713
00714
00715 bool IniRead (
00716 INIHANDLE IniHandle,
00717 const char *IniGroup,
00718 const char *IniName
00719 ) { return (_iniRead(IniHandle,IniGroup,IniName,INITYPE_DRECT2D,this,1) == 1); }
00720
00721
00722 bool IniRead (
00723 INIHANDLE IniHandle,
00724 const char *IniGroup,
00725 const char *IniName,
00726 const DRECT2D& dft
00727 ) { if (IniRead(IniHandle,IniGroup,IniName)) return (true); else { *this = dft; return (false); } }
00728
00729
00730 void IniWrite (
00731 INIHANDLE IniHandle,
00732 const char *IniGroup,
00733 const char *IniName
00734 ) const { _iniWrite(IniHandle,IniGroup,IniName,INITYPE_DRECT2D,this,1); }
00735
00736
00737 void Intersect (
00738 const DRECT2D& rect
00739 ) {
00740 if (rect.IsValid()) {
00741 if (rect.xinit > xinit) xinit = rect.xinit;
00742 if (rect.yinit > yinit) yinit = rect.yinit;
00743 if (rect.xlast < xlast) xlast = rect.xlast;
00744 if (rect.ylast < ylast) ylast = rect.ylast;
00745 }
00746 else {
00747 *this = rect;
00748 }
00749 return;
00750 }
00751
00752
00753
00754
00755
00756 bool IsEquivalentTo (
00757 const DRECT2D& rhs,
00758 double threshold = 0.0
00759 ) const { return (DRect2DIsEquivalentTo(*this, rhs, threshold)); }
00760
00761
00762 bool IsValid (
00763 ) const { return (xinit <= xlast && yinit <= ylast); }
00764
00765
00766 void Limit (
00767 DPOINT2D& point
00768 ) const {
00769 if (point.x < xinit) point.x = xinit; else if (point.x > xlast) point.x = xlast;
00770 if (point.y < yinit) point.y = yinit; else if (point.y > ylast) point.y = ylast;
00771 return;
00772 }
00773
00774
00775 bool Overlaps (
00776 const DRECT2D& rhs
00777 ) const { return (!(rhs.xlast < xinit || rhs.xinit > xlast || rhs.ylast < yinit || rhs.yinit > ylast)); }
00778
00779
00780 void Set (
00781 double x1,
00782 double y1,
00783 double x2,
00784 double y2
00785 ) { xinit = x1; yinit = y1; xlast = x2; ylast = y2; }
00786
00787
00788
00789
00790
00791 void SetInvalid (
00792 ) { xinit = yinit = DBL_MAX; xlast = ylast = -DBL_MAX; }
00793
00794
00795 void SwapBytes (
00796 ) { ::SwapBytes(xinit); ::SwapBytes(xlast); ::SwapBytes(yinit); ::SwapBytes(ylast); }
00797
00798
00799 CHECKSIZE(32);
00800 };
00801
00802 inline bool operator== (
00803 const DRECT2D& lhs,
00804 const DRECT2D& rhs
00805 ) {
00806 return (lhs.xinit == rhs.xinit && lhs.xlast == rhs.xlast && lhs.yinit == rhs.yinit && lhs.ylast == rhs.ylast);
00807 }
00808
00809 inline bool operator!= (
00810 const DRECT2D& lhs,
00811 const DRECT2D& rhs
00812 ) {
00813 return (!operator==(lhs,rhs));
00814 }
00815
00816 inline void SwapBytes (
00817 DRECT2D& rect
00818 ) {
00819 rect.SwapBytes();
00820 }
00821
00822
00823 inline int IniRead (INIHANDLE hdl, const char *group, const char *field, DRECT2D& value) { return (_iniRead(hdl,group,field,INITYPE_DRECT2D,&value,1)); }
00824
00825
00826 inline int IniRead (INIHANDLE hdl, const char *group, const char *field, DRECT2D& value, const DRECT2D& dft) { value = dft; return (IniRead(hdl,group,field,value)); }
00827
00828
00829 inline int IniWrite (INIHANDLE hdl, const char *group, const char *field, const DRECT2D& value) { return (_iniWrite(hdl,group,field,INITYPE_DRECT2D,&value,1)); }
00830
00831
00832
00833
00834
00835 struct DRECT3D : public DRECT2D {
00836
00837 double zinit;
00838 double zlast;
00839
00840
00841 DRECT3D (
00842 ) : DRECT2D(), zinit(DBL_MAX), zlast(-DBL_MAX) { }
00843
00844
00845 DRECT3D (
00846 const FPOINT3D& pt
00847 ) : DRECT2D(pt), zinit(pt.z), zlast(pt.z) { }
00848
00849
00850 DRECT3D (
00851 const DPOINT3D& pt
00852 ) : DRECT2D(pt), zinit(pt.z), zlast(pt.z) { }
00853
00854
00855
00856
00857 DRECT3D (
00858 const DPOINT3D& pt1,
00859 const DPOINT3D& pt2
00860 ) {
00861 if (pt1.x < pt2.x) {
00862 xinit = pt1.x;
00863 xlast = pt2.x;
00864 }
00865 else {
00866 xinit = pt2.x;
00867 xlast = pt1.x;
00868 }
00869 if (pt1.y < pt2.y) {
00870 yinit = pt1.y;
00871 ylast = pt2.y;
00872 }
00873 else {
00874 yinit = pt2.y;
00875 ylast = pt1.y;
00876 }
00877 if (pt1.z < pt2.z) {
00878 zinit = pt1.z;
00879 zlast = pt2.z;
00880 }
00881 else {
00882 zinit = pt2.z;
00883 zlast = pt1.z;
00884 }
00885 }
00886
00887
00888 DRECT3D (
00889 const DRECT2D& rect
00890 ) : DRECT2D(rect), zinit(0.0), zlast(0.0) { }
00891
00892
00893 DRECT3D (
00894 const DRECT2D& rect,
00895 double zmin,
00896 double zmax
00897 ) : DRECT2D(rect), zinit(zmin), zlast(zmax) { }
00898
00899
00900 DRECT3D& operator= (
00901 const DPOINT3D& pt
00902 ) {
00903 xinit = xlast = pt.x;
00904 yinit = ylast = pt.y;
00905 zinit = zlast = pt.z;
00906 return (*this);
00907 }
00908
00909
00910 bool Contains (
00911 const DPOINT3D& pt
00912 ) const { return (DRECT2D::Contains(pt) && pt.z >= zinit && pt.z <= zlast); }
00913
00914
00915 bool Contains (
00916 const DRECT3D& rhs
00917 ) const { return (DRECT2D::Contains(rhs) && rhs.zinit >= zinit && rhs.zlast <= zlast); }
00918
00919
00920 void Expand (
00921 const double value
00922 ) {
00923 DRECT2D::Expand(value);
00924 zinit -= value; zlast += value;
00925 return;
00926 }
00927
00928
00929 void Expand (
00930 const double xval,
00931 const double yval
00932 ) { DRECT2D::Expand(xval, yval); }
00933
00934
00935 void Extend (
00936 const double xval,
00937 const double yval
00938 ) { DRECT2D::Extend(xval, yval); }
00939
00940
00941 void Extend (
00942 const double xval,
00943 const double yval,
00944 const double zval
00945 ) {
00946 DRECT2D::Extend(xval, yval);
00947 if (zval < zinit) zinit = zval;
00948 if (zval > zlast) zlast = zval;
00949 return;
00950 }
00951
00952
00953 void Extend (
00954 const DRECT3D& rect
00955 ) {
00956 DRECT2D::Extend(rect);
00957 if (rect.zinit < zinit) zinit = rect.zinit;
00958 if (rect.zlast > zlast) zlast = rect.zlast;
00959 return;
00960 }
00961
00962
00963 void Extend (
00964 const DPOINT2D& pt
00965 ) { DRECT2D::Extend(pt); }
00966
00967
00968 void Extend (
00969 const DPOINT3D& pt
00970 ) {
00971 DRECT2D::Extend(pt);
00972 if (pt.z < zinit) zinit = pt.z;
00973 if (pt.z > zlast) zlast = pt.z;
00974 return;
00975 }
00976
00977
00978 DPOINT3D GetCenter (
00979 ) const { return (DPOINT3D((xinit+xlast)/2.0,(yinit+ylast)/2.0,(zinit+zlast)/2.0)); }
00980
00981
00982 void GetCenter (
00983 DPOINT3D& ret
00984 ) const {
00985 ret.x = (xinit + xlast) / 2.0;
00986 ret.y = (yinit + ylast) / 2.0;
00987 ret.z = (zinit + zlast) / 2.0;
00988 return;
00989 }
00990
00991
00992 double GetDepth (
00993 ) const { return (zlast - zinit); }
00994
00995
00996 int GetDimension (
00997 ) const {
00998 int count(DRECT2D::GetDimension());
00999 if (zinit < zlast) count ++;
01000 return (count);
01001 }
01002
01003
01004 void GetMaximum (
01005 DPOINT3D& maximum
01006 ) const { maximum.x = xlast; maximum.y = ylast; maximum.z = zlast; }
01007
01008
01009 void GetMinimum (
01010 DPOINT3D& minimum
01011 ) const { minimum.x = xinit; minimum.y = yinit; minimum.z = zinit; }
01012
01013
01014 void GetSize (
01015 DPOINT3D& ret
01016 ) const {
01017 ret.x = xlast - xinit;
01018 ret.y = ylast - yinit;
01019 ret.z = zlast - zinit;
01020 return;
01021 }
01022
01023
01024 double GetVolume (
01025 ) const { return (DRECT2D::GetArea() * (zlast - zinit)); }
01026
01027
01028 bool IniRead (
01029 INIHANDLE IniHandle,
01030 const char *IniGroup,
01031 const char *IniName
01032 ) { return (_iniRead(IniHandle,IniGroup,IniName,INITYPE_Double,this,6) == 6); }
01033
01034
01035 void IniWrite (
01036 INIHANDLE IniHandle,
01037 const char *IniGroup,
01038 const char *IniName
01039 ) const { _iniWrite(IniHandle,IniGroup,IniName,INITYPE_Double,this,6); }
01040
01041
01042 void Intersect (
01043 const DRECT3D& rect
01044 ) {
01045 if (rect.IsValid()) {
01046 DRECT2D::Intersect(rect);
01047 if (rect.zinit > zinit) zinit = rect.zinit;
01048 if (rect.zlast < zlast) zlast = rect.zlast;
01049 }
01050 else {
01051 *this = rect;
01052 }
01053 return;
01054 }
01055
01056
01057 bool IsValid (
01058 ) const { return (DRECT2D::IsValid() && zinit <= zlast); }
01059
01060
01061 bool Overlaps (
01062 const DRECT3D& rhs
01063 ) const { return (DRECT2D::Overlaps(rhs) && !(rhs.zlast < zinit || rhs.zinit > zlast)); }
01064
01065
01066 void Set (
01067 double x1,
01068 double y1,
01069 double x2,
01070 double y2
01071 ) { xinit = x1; yinit = y1; xlast = x2; ylast = y2; zinit = zlast = 0.0; }
01072
01073
01074
01075
01076
01077
01078 void SetInvalid (
01079 ) { DRECT2D::SetInvalid(); zinit = DBL_MAX; zlast = -DBL_MAX; }
01080
01081
01082 void SwapBytes (
01083 ) { ::SwapBytes(xinit); ::SwapBytes(xlast); ::SwapBytes(yinit); ::SwapBytes(ylast); ::SwapBytes(zinit); ::SwapBytes(zlast); }
01084
01085
01086 CHECKSIZE(48);
01087 };
01088
01089 inline bool operator== (
01090 const DRECT3D& lhs,
01091 const DRECT3D& rhs
01092 ) {
01093 return (lhs.xinit == rhs.xinit && lhs.xlast == rhs.xlast && lhs.yinit == rhs.yinit && lhs.ylast == rhs.ylast && lhs.zinit == rhs.zinit && lhs.zlast == rhs.zlast);
01094 }
01095
01096 inline bool operator!= (
01097 const DRECT3D& lhs,
01098 const DRECT3D& rhs
01099 ) {
01100 return (!operator==(lhs,rhs));
01101 }
01102
01103 inline void SwapBytes (
01104 DRECT3D& rect
01105 ) {
01106 rect.SwapBytes();
01107 }
01108
01109
01110
01111
01112 #endif