最小外包矩形对象的封装
最小外包矩形MBR就是包围图元,且平行于X,Y轴的最小外接矩形。
- 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 segment
- double 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 segment
- double 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;
- }
- };