The minimum outsourcing rectangle MBR is the smallest external rectangle that is enclosed in elements and parallel to X and Y axes.
template<class T> struct CGeoRect { // Four corner points T m_minX; T m_minY; T m_maxX; T m_maxY; // // Constructors and deconstructor // /** * Default constructor with no any sense.** Note: * 1) If passed by self-defined data type, it must have copy constructor being responsible for* converting doulbe to it.* 2) Since we adopt UEZERO as invalid point which makes sense when not initialized before being used, * we had better notice the assertion happen before correctly using one geometry. */ CGeoRect() : m_minX(-1.), m_minY(-1.), m_maxX(-1.), m_maxY(-1.) { } /** * Default constructor with specified corner values. */ CGeoRect(const T &minX, const T &minY, const T &maxX, const T& maxY) : m_minX(minX), m_minY(minY), m_maxX(maxX), m_maxY(maxY) { } /** * Copy constructor.** Note: If passed by self-defined data type, it must overload assignment operator */ CGeoRect(const CGeoRect &other) { m_minX = other.m_minX; m_maxY = other.m_maxY; m_maxX = other.m_maxX; m_minY = other.m_minY; } /*** Deconstructor.* * Note:Since we want to take it as inner built-in type, it no need to inherit children and * virtual constructor may cause different behavior when against different compilers */ ~CGeoRect() { } // // Simple interfaces ///** * Check whether is an valid rectangle.**/bool IsValid() const{return !((m_minX == m_maxX && m_minX == static_cast<T>(UE_INVALIDCOORD)) ||(m_minY == m_maxY && m_minY == static_cast<T>(UE_INVALIDCOORD)));} /** * Disable this rectangle. */ void Empty() { m_minX = m_maxX = m_minY = m_maxY = static_cast<T>(UE_ZERO); } /** * Check whether is an rectangle have an validate area. */ bool IsEmpty() const {//assert(IsValid());return (m_minX == m_maxX || m_maxY == m_minY || (m_maxX - m_minX) < static_cast<T>(RECTLIMIT) || (m_maxY - m_minY) < static_cast<T>(RECTLIMIT)); } /** * Check whether intersect another rectangle. */ inline bool IsIntersect(const CGeoRect<T> &other) const {//assert(IsValid()); if(m_maxY < other.m_minY ||m_minY > other.m_maxY ||m_maxX < other.m_minX || m_minX > other.m_maxX) { return false; } return true; } /** * Check whether contains another smaller rectangle including overstacked borders. */ bool IsContain(const CGeoRect<T> &other) const {if(IsValid()){if(other.m_minX >= m_minX && other.m_maxX <= m_maxX && other.m_minY >= m_minY && other.m_maxY <= m_maxY){return true;}} return false; } /** * Check whether contain one point. */ bool IsContain(const CGeoPoint<T> &point) {if(IsValid()){// Exception even if given this rectangle as one line segmentdouble minX = m_minX;double maxX = m_maxX;if(m_minX == m_maxX){minX -= 5;maxX += 5;}// Exception even if given this rectangle as one line segmentdouble minY = m_minY;double maxY = m_maxY;if(m_minY == m_maxY){minY -= 5;maxY += 5;}if(point.m_x < minX ||point.m_x > maxX ||point.m_y < minY ||point.m_y > maxY){return false;} return true;}return false; } /** * Check whether contain one point. */ bool IsContain(const CGeoPoint<T> &point) const {//assert(IsValid()); if(point.m_x < m_minX || point.m_x > m_maxX || point.m_y < m_minY || point.m_y > m_maxY) { return false; } return true; } /** * Union two rectangles. */ void Union(const CGeoRect<T> &other) {//assert(IsValid()); if(m_minX > other.m_minX) { m_minX = other.m_minX; } if(m_maxX < other.m_maxX) { m_maxX = other.m_maxX; } if(m_minY > other.m_minY) { m_minY = other.m_minY; } if(m_maxY < other.m_maxY) { m_maxY = other.m_maxY; } }/*** Enlarge this rectangle.*/bool Inflate(T xShift, T yShift){//assert(IsValid());m_minX -= xShift;m_maxX += xShift;m_minY -= yShift;m_maxY += yShift;return !IsEmpty();}/*** Shrink this rectangle.*/bool Deflate(T xShift, T yShift){//assert(IsValid());m_minX += xShift;m_maxX -= xShift;m_minY += yShift;m_maxY -= yShift;return !IsEmpty();} /** * Get rectangle width. */ T Width() const {//assert(IsValid()); return m_maxX - m_minX; } /** * Get rectangle height. */ T Height() const {//assert(IsValid()); return m_maxY - m_minY; } // // Useful overloaded operators // /** * Overload assignment operator. */ const CGeoRect &operator = (const CGeoRect &other) {//assert(other.IsValid()); if(this == &other) { return *this; } m_minX = other.m_minX; m_maxY = other.m_maxY; m_maxX = other.m_maxX; m_minY = other.m_minY; return *this; } /** * Overload bool operator. */ bool operator == (const CGeoRect &other) const {//assert(IsValid());if(m_minX == other.m_minX && m_maxY == other.m_maxY && m_maxX == other.m_maxX && m_minY == other.m_minY) { return true; } return false; } };