MrSID Decode SDK for Raster Reference Manual  9.5.1.4427
lti_geometry.h
Go to the documentation of this file.
00001 /* $Id$ */
00002 /* //////////////////////////////////////////////////////////////////////////
00003 //                                                                         //
00004 // This code is Copyright (c) 2004 LizardTech, Inc, 1008 Western Avenue,   //
00005 // Suite 200, Seattle, WA 98104.  Unauthorized use or distribution         //
00006 // prohibited.  Access to and use of this code is permitted only under     //
00007 // license from LizardTech, Inc.  Portions of the code are protected by    //
00008 // US and foreign patents and other filings. All Rights Reserved.          //
00009 //                                                                         //
00011 
00012 #ifndef LTI_GEOMETRY_H
00013 #define LTI_GEOMETRY_H
00014 
00015 // lt_lib_mrsid_core
00016 #include "lti_types.h"
00017 
00018 LT_BEGIN_NAMESPACE(LizardTech)
00019 
00020 
00021 template<class T>
00022 class LTIGeomPoint
00023 {
00024 public:
00025    LTIGeomPoint(T inX = 0, T inY = 0) :
00026       x(inX),
00027       y(inY)
00028    {
00029    }
00030 
00031    //   ------------------------------
00032    //   *   copy constructor
00033    //   ------------------------------
00034    LTIGeomPoint(const LTIGeomPoint<T>& copy) :
00035       x(copy.x),
00036       y(copy.y)
00037 
00038    {
00039    }
00040 
00041    //   ------------------------------
00042    //   *   assignment operator
00043    //   ------------------------------
00044    LTIGeomPoint<T>& operator=(const LTIGeomPoint<T>& copy)
00045    {
00046       x = copy.x;
00047       y = copy.y;
00048       return *this;
00049    }
00050 
00051 
00052    //   ----------------------------
00053    //   *   addition
00054    //   ----------------------------
00055    template<class T2>
00056    LTIGeomPoint<T>& operator +=(const LTIGeomPoint<T2>& offset)
00057    {
00058       x += offset.x;
00059       y += offset.y;
00060       return *this;
00061    }
00062 
00063    //   ----------------------------
00064    //   *   subtraction
00065    //   ----------------------------
00066    template<class T2>
00067    LTIGeomPoint<T>& operator -=(const LTIGeomPoint<T2>& offset)
00068    {
00069       x -= offset.x;
00070       y -= offset.y;
00071       return *this;
00072    }
00073 
00074    //   --------------------------------------------------------
00075    //   *   equality operator
00076    //   --------------------------------------------------------
00077    inline bool operator ==(const LTIGeomPoint<T>& other) const
00078    {
00079       return x == other.x && y == other.y;
00080    }
00081 
00082    //   --------------------------------------------------------
00083    //   *   not equals operator
00084    //   --------------------------------------------------------
00085    inline bool operator !=(const LTIGeomPoint<T>& other) const
00086    {
00087       return !operator==(other);
00088    }
00089 
00090    inline bool equal(const LTIGeomPoint<T>& other, T eps) const
00091    {
00092       return (x < other.x ? other.x - x : x - other.x) <= eps &&
00093              (y < other.y ? other.y - y : y - other.y) <= eps;
00094    }
00095 
00096 public:
00097    //   --------------------------------------------------------
00098    //   *   Data
00099    //   --------------------------------------------------------
00100    T x;
00101    T y;
00102 };
00103 
00104 
00105 
00106 //   --------------------------------------------------------------
00107 //   *   global point operators
00108 //   --------------------------------------------------------------
00109 template<class T>
00110 LTIGeomPoint<T> operator+(const LTIGeomPoint<T>& p1, const  LTIGeomPoint<T>& p2)
00111 {
00112    LTIGeomPoint<T> p3 = p1;
00113    p3 += p2;
00114    return p3;
00115 }
00116 
00117 template<class T>
00118 LTIGeomPoint<T> operator-(const LTIGeomPoint<T>& p1, const  LTIGeomPoint<T>& p2)
00119 {
00120    LTIGeomPoint<T> p3 = p1;
00121    p3 -= p2;
00122    return p3;
00123 }
00124 
00125 
00126 
00127 
00128 //   ----------------------------------------
00129 //
00130 //            Dimensions
00131 //
00132 //   ----------------------------------------
00133 
00134 template<class T>
00135 class LTIGeomDim
00136 {
00137 public:
00138    LTIGeomDim(T w = 0, T h = 0) :
00139      width(w),
00140      height(h)
00141    {}
00142 
00143    LTIGeomDim(const LTIGeomDim<T>& other) :
00144      width(other.width),
00145      height(other.height)
00146    {}
00147 
00148    LTIGeomDim<T>& operator=(const LTIGeomDim<T>& other)
00149    {
00150       width = other.width;
00151       height = other.height;
00152       return *this;
00153    }
00154 
00155    bool operator==(const LTIGeomDim<T>& other) const
00156    {
00157       return width == other.width && height == other.height;
00158    }
00159 
00160    bool operator!=(const LTIGeomDim<T>& other) const
00161    {
00162       return !operator==(other);
00163    }
00164 
00165 public:
00166    T width;
00167    T height;
00168 };
00169 
00170 
00171 
00172 //   ------------------------------------------------------------
00173 //
00174 //            Rectangles
00175 //
00176 //   The LTIGeomRect class represents rectangles in 2 dimensional space.
00177 //   A rectangle is defined as having an upper left and a lower right corner.
00178 //   +X goes to the right and +Y goes down. (It is a left handed world.)
00179 //
00180 //   ------------------------------------------------------------
00181 
00182 template<class T, bool inclusive = true>
00183 class LTIGeomRect
00184 {
00185 public:
00186    //   ------------------------------------------------------------
00187    //   *   Construct from 2 points
00188    //   ------------------------------------------------------------
00189    LTIGeomRect(const LTIGeomPoint<T>& inUL, const LTIGeomPoint<T>& inLR) :
00190       uLeft(inUL),
00191       lRight(inLR)
00192    {}
00193 
00194    //   ------------------------------------------------------------
00195    //   *   Construct from 4 values - the first pair is upper left,
00196    //    second pair is lower right
00197    //   ------------------------------------------------------------
00198    LTIGeomRect(T ulx=0, T uly=1, T lrx=-1, T lry=0) :
00199       uLeft(ulx, uly),
00200       lRight(lrx, lry)
00201    {}
00202 
00203 
00204    //   ------------------------------------------------------------
00205    //   *   Construct from a dimension
00206    // Resulting rect has uLeft = (0,0) and dimensions d
00207    //   ------------------------------------------------------------
00208    LTIGeomRect(const LTIGeomDim<T> d) :
00209       uLeft(0,0),
00210       lRight(d.width - (inclusive ? 1 : 0), d.height - (inclusive ? 1 : 0))
00211    {}
00212 
00213    //   ------------------------------------------------------------
00214    //   *   Copy constructor
00215    //   ------------------------------------------------------------
00216       LTIGeomRect(const LTIGeomRect<T, inclusive>& copy) :
00217       uLeft(copy.uLeft),
00218       lRight(copy.lRight)
00219    {}
00220 
00221    //   ------------------------------------------------------------
00222    //   *   Assignment operator
00223    //   ------------------------------------------------------------
00224    LTIGeomRect<T, inclusive>& operator=(const LTIGeomRect<T, inclusive>& copy)
00225    {
00226       uLeft = copy.uLeft;
00227       lRight = copy.lRight;
00228       return *this;
00229    }
00230 
00231    //   ------------------------------------------------------------
00232    //   *   width
00233    //   ------------------------------------------------------------
00234    T getWidth() const
00235    {
00236       return (lRight.x - uLeft.x) + (T)(inclusive ? 1 : 0);
00237    }
00238    T width() const { return getWidth(); }    // BUG: api change
00239 
00240    //   ------------------------------------------------------------
00241    //   *   height
00242    //   ------------------------------------------------------------
00243    T getHeight() const
00244    {
00245       return (lRight.y - uLeft.y) + (T)(inclusive ? 1 : 0);
00246    }
00247    T height() const { return getHeight(); }  // BUG: api change
00248 
00249    //   ------------------------------------------------------------
00250    //   *   isEmpty
00251    //   ------------------------------------------------------------
00252    bool isEmpty() const
00253    {
00254       return getWidth() <= 0 || getHeight() <= 0;
00255    }
00256 
00257    //   ------------------------------------------------------------
00258    //   *   dimensions
00259    //   ------------------------------------------------------------
00260    LTIGeomDim<T> getDimensions() const
00261    {
00262       return LTIGeomDim<T>(getWidth(), getHeight());
00263    }
00264 
00265    //   ------------------------------------------------------------
00266    //   *   returns center point of the rectangle
00267    //   ------------------------------------------------------------
00268    LTIGeomPoint<T> getCenter() const
00269    {
00270       T cx = uLeft.x + getWidth()/2;
00271       T cy = uLeft.y + getHeight()/2;
00272       return LTIGeomPoint<T>(cx, cy);
00273    }
00274 
00275 
00276     //   ------------------------------------------------------------
00277    //   *   location
00278    // returns the location of the specified reference point
00279    //   ------------------------------------------------------------
00280    LTIGeomPoint<T> location(LTIPosition referencePoint)
00281    {
00282       LTIGeomPoint<T> ref = uLeft;
00283       switch (referencePoint)
00284       {
00285          case LTI_POSITION_UPPER_LEFT:
00286             break;
00287          case LTI_POSITION_UPPER_CENTER:
00288             ref.x += static_cast<T>(getWidth()/2.0);
00289             break;
00290          case LTI_POSITION_UPPER_RIGHT:
00291             ref.x = static_cast<T>(lRight.x);
00292             break;
00293 
00294          case LTI_POSITION_CENTER_LEFT:
00295             ref.y -= static_cast<T>(-getHeight()/2.0);
00296             break;
00297          case LTI_POSITION_CENTER:
00298             ref.x += static_cast<T>(getWidth()/2.0);
00299             ref.y -= static_cast<T>(-getHeight()/2.0);
00300             break;
00301          case LTI_POSITION_CENTER_RIGHT:
00302             ref.x = static_cast<T>(lRight.x);
00303             ref.y -= static_cast<T>(-getHeight()/2.0);
00304             break;
00305 
00306          case LTI_POSITION_LOWER_LEFT:
00307             ref.y = static_cast<T>(lRight.y);
00308             break;
00309          case LTI_POSITION_LOWER_CENTER:
00310             ref.y = static_cast<T>(lRight.y);
00311             ref.x += static_cast<T>(getWidth()/2.0);
00312             break;
00313          case LTI_POSITION_LOWER_RIGHT:
00314             ref = lRight;
00315             break;
00316       }
00317       return ref;
00318    }
00319 
00320 
00321    //   ------------------------------------------------------------
00322    //   *   addition
00323    //   moves the restangle by an offset
00324    //   ------------------------------------------------------------
00325    template<class T2>
00326    LTIGeomRect<T, inclusive>& operator+=(const LTIGeomPoint<T2>& offset)
00327    {
00328       uLeft += offset;
00329       lRight += offset;
00330       return *this;
00331    }
00332 
00333    //   ------------------------------------------------------------
00334    //   *   subtraction
00335    //   moves the restangle by an offset
00336    //   ------------------------------------------------------------
00337    template<class T2>
00338    LTIGeomRect<T, inclusive>& operator-=(const LTIGeomPoint<T2>& offset)
00339    {
00340       uLeft -= offset;
00341       lRight -= offset;
00342       return *this;
00343    }
00344 
00345    //   ------------------------------------------------------------
00346    //   *   intersection operator
00347    //   returns the intersection between two rectangles
00348    //   ------------------------------------------------------------
00349    LTIGeomRect<T, inclusive>& operator &=(const LTIGeomRect<T, inclusive>& other)
00350    {
00351       if(!intersect(other))
00352          *this = LTIGeomRect();  // invalid rectangle
00353       return *this;
00354    }
00355 
00356    //   ------------------------------------------------------------
00357    //   *   union operator
00358    //   returns the union of two rectangles
00359    //   ------------------------------------------------------------
00360    LTIGeomRect<T, inclusive>& operator |=(const LTIGeomRect<T, inclusive>& other)
00361    {
00362       uLeft.x = LT_MIN(uLeft.x, other.uLeft.x);
00363       uLeft.y = LT_MIN(uLeft.y, other.uLeft.y);
00364       lRight.x = LT_MAX(lRight.x, other.lRight.x);
00365       lRight.y = LT_MAX(lRight.y, other.lRight.y);
00366       return *this;
00367    }
00368 
00369    bool operator==(const LTIGeomRect<T, inclusive>& other) const
00370    {
00371       return uLeft == other.uLeft && lRight == other.lRight;
00372    }
00373 
00374    //   --------------------------------------------------------
00375    //   *   not equals operator
00376    //   --------------------------------------------------------
00377    inline bool operator !=(const LTIGeomRect<T, inclusive>& other) const
00378    {
00379       return !operator==(other);
00380    };
00381 
00382    // clip our rectangle to the given size, i.e. do an intersection
00383    // return true iff we remain a valid rectangle
00384    bool intersect(const LTIGeomRect<T, inclusive>& other)
00385    {
00386       uLeft.x = LT_MAX(uLeft.x, other.uLeft.x);
00387       uLeft.y = LT_MAX(uLeft.y, other.uLeft.y);
00388       lRight.x = LT_MIN(lRight.x, other.lRight.x);
00389       lRight.y = LT_MIN(lRight.y, other.lRight.y);
00390 
00391       return uLeft.x <= lRight.x && uLeft.y <= lRight.y;
00392    }
00393 
00394 public:
00395    //   ------------------------------------------------
00396    //   *   Data
00397    //   ------------------------------------------------
00398    LTIGeomPoint<T> uLeft;   //   upper left corner
00399    LTIGeomPoint<T> lRight;   //   lower right corner
00400 };
00401 
00402 
00403 //   --------------------------------------------------------------
00404 //   *   global rect operators
00405 //   --------------------------------------------------------------
00406 template<class T, bool inclusive>
00407 LTIGeomRect<T, inclusive> operator+(const LTIGeomRect<T, inclusive>& r1,
00408                                      const LTIGeomPoint<T>& offset)
00409 {
00410    LTIGeomRect<T, inclusive> r3 = r1;
00411    r3 += offset;
00412    return r3;
00413 }
00414 
00415 template<class T, bool inclusive>
00416 LTIGeomRect<T, inclusive> operator-(const LTIGeomRect<T, inclusive>& r1,
00417                                      const LTIGeomPoint<T>& offset)
00418 {
00419    LTIGeomRect<T, inclusive> r3 = r1;
00420    r3 -= offset;
00421    return r3;
00422 }
00423 
00424 template<class T, bool inclusive>
00425 LTIGeomRect<T, inclusive> operator&(const LTIGeomRect<T, inclusive>& r1,
00426                                      const LTIGeomRect<T, inclusive>& r2)
00427 {
00428    LTIGeomRect<T, inclusive> r3 = r1;
00429    r3 &= r2;
00430    return r3;
00431 }
00432 
00433 template<class T, bool inclusive>
00434 LTIGeomRect<T, inclusive> operator|(const LTIGeomRect<T, inclusive>& r1,
00435                                      const LTIGeomRect<T, inclusive>& r2)
00436 {
00437    LTIGeomRect<T, inclusive> r3 = r1;
00438    r3 |= r2;
00439    return r3;
00440 }
00441 
00442 
00443 //   ------------------------------------------------------------
00444 //
00445 //            Bound Box
00446 //
00447 //   The LTIGeomBBox class represents rectangles in 2 dimensional space.
00448 //   A rectangle is defined as having a min point and a max point.
00449 //   +X goes to the right and +Y goes up.  (It is a right handed world.)
00450 //
00451 //   ------------------------------------------------------------
00452 
00453 template<class T>
00454 class LTIGeomBBox
00455 {
00456 public:
00457    LTIGeomBBox(T minX = 0, T minY = 0, T maxX = 0, T maxY = 0) :
00458       xMin(minX),
00459       yMin(minY),
00460       xMax(maxX),
00461       yMax(maxY)
00462    {}
00463 
00464    LTIGeomBBox(const LTIGeomBBox<T>& copy) :
00465       xMin(copy.xMin),
00466       yMin(copy.yMin),
00467       xMax(copy.xMax),
00468       yMax(copy.yMax)
00469    {}
00470 
00471    LTIGeomBBox<T>& operator=(const LTIGeomBBox<T>& copy)
00472    {
00473       xMin = copy.xMin;
00474       yMin = copy.yMin;
00475       xMax = copy.xMax;
00476       yMax = copy.yMax;
00477       return *this;
00478    }
00479 
00480    T getWidth() const  { return xMax - xMin; }
00481    T getHeight() const { return yMax - yMin; }
00482    bool isEmpty() const { return xMax <= xMin || yMax <= yMin; }
00483    LTIGeomPoint<T> getCenter() const
00484    {
00485       return LTIGeomPoint<T>((xMin + xMax) / 2, (yMin + yMax) / 2);
00486    }
00487 
00488    // intersection operator
00489    LTIGeomBBox<T>& operator &=(const LTIGeomBBox<T>& other)
00490    {
00491       xMin = LT_MAX(xMin, other.xMin);
00492       yMin = LT_MAX(yMin, other.yMin);
00493       xMax = LT_MIN(xMax, other.xMax);
00494       yMax = LT_MIN(yMax, other.yMax);
00495       return *this;
00496    }
00497 
00498    // union operator
00499    LTIGeomBBox<T>& operator |=(const LTIGeomBBox<T>& other)
00500    {
00501       xMin = LT_MIN(xMin, other.xMin);
00502       yMin = LT_MIN(yMin, other.yMin);
00503       xMax = LT_MAX(xMax, other.xMax);
00504       yMax = LT_MAX(yMax, other.yMax);
00505       return *this;
00506    }
00507 
00508    bool overlap(const LTIGeomBBox<T>& other) const
00509    {
00510       if(xMin > other.xMax || other.xMin > xMax)
00511          return false;
00512       if(yMin > other.yMax || other.yMin > yMax)
00513          return false;
00514       return true;
00515    }
00516 
00517    bool containsPoint(const LTIGeomPoint<T> &pt) const
00518    {
00519       return (xMin <= pt.x && pt.x <= xMax) &&
00520              (yMin <= pt.y && pt.y <= yMax);
00521    }
00522 
00523    // equalty operators
00524    bool operator ==(const LTIGeomBBox<T>& other) const
00525    {
00526       return xMin == other.xMin &&
00527              yMin == other.yMin &&
00528              xMax == other.xMax &&
00529              yMax == other.yMax;
00530    }
00531    bool operator !=(const LTIGeomBBox<T>& other) const
00532    {
00533       return !operator==(other);
00534    }
00535 
00536 public:
00537    T xMin;
00538    T yMin;
00539    T xMax;
00540    T yMax;
00541 };
00542 
00543 typedef LTIGeomRect<lt_int32, true>  LTIGeomIntRect;
00544 typedef LTIGeomDim<lt_int32>         LTIGeomIntDim;
00545 typedef LTIGeomPoint<lt_int32>       LTIGeomIntPoint;
00546 
00547 typedef LTIGeomRect<double, false>   LTIGeomDblRect;
00548 typedef LTIGeomDim<double>           LTIGeomDblDim;
00549 typedef LTIGeomPoint<double>         LTIGeomDblPoint;
00550 
00551 // BUG: these just for backwards compatability (mg3)
00552 typedef LTIGeomRect<lt_int32, true>  MG3Rect;
00553 typedef LTIGeomDim<lt_int32>         MG3Dim;
00554 typedef LTIGeomPoint<lt_int32>       MG3Point;
00555 
00556 // BUG: these just for backwards compatability (mg2)
00557 typedef LTIGeomRect<lt_int32, true>  IntRect;
00558 typedef LTIGeomDim<lt_int32>         IntDimension;
00559 typedef LTIGeomPoint<lt_int32>       IntPoint;
00560 
00561 LT_END_NAMESPACE(LizardTech)
00562 
00563 
00564 #endif // LTI_GEOMETRY_H