計算幾何算法五:矩形框

繼承多邊形的矩形框,主要包括:與點的關係,面積、與矩形框的重合面積

// RtRect.h: interface for the CRtRect class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_RTRECT_H__9063CA03_F523_475A_A7E7_C6405A9C5D00__INCLUDED_)
#define AFX_RTRECT_H__9063CA03_F523_475A_A7E7_C6405A9C5D00__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "define.h"
#include "RtPolygon.h"

template< class T >
class CRtRect: public CRtPolygon<T>
{
public:
 //constructor
 CRtRect(): mvo_height(0), mvo_width(0)
 {}
 CRtRect( const CRtPoint<T>& in, T width, T height ): mvo_data(in), mvo_height(height), mvo_width(width)
 {
  Conversion();
 }
 CRtRect( const T left, const T right, const T top, const T bottom)
 {
  mvo_data.SetData( left, top );
  mvo_width = right - left;
  mvo_height = (T)fabs( top - bottom );
  Conversion();
 }

 //copy constructor
 CRtRect( const CRtRect& in )
 {
  mvo_data = in.mvo_data;
  mvo_height = in.mvo_height;
  mvo_width = in.mvo_width;
  Conversion();
 }

 //destructor
 virtual ~CRtRect()
 {}

//operators overload:
 //Rectangle Equality, epsilon used due to numerical imprecision
 bool operator == ( const CRtRect<T>& in )
 {
  return mvo_data == in.mvo_data && fabs(mvo_height - in.mvo_height) < MINERR && fabs(mvo_width - in.mvo_width) < MINERR ;
 }
 
 //evaluate to rectangle
 const CRtRect& operator = ( const CRtRect<T>& in )
 {
  mvo_data = in.mvo_data;
  mvo_height = in.mvo_height;
  mvo_width = in.mvo_width;
  Conversion();

  return *this;
 }

 void SetData( const CRtPoint<T>& in, T width, T height )
 {
  mvo_data = in;
  mvo_height = height;
  mvo_width = width;

  Conversion();
 }
 void SetData( const T left, const T right, const T top, const T bottom)
 {
  mvo_data.SetData( left, top );
  mvo_width = right - left;
  mvo_height = bottom - top;
  Conversion();
 }

 //araa
 double Area()
 {
  return mvo_height * mvo_width;
 }

 //the relation a point and rectangle
 virtual int RelationPoint( CRtPoint<T>& in);

 //the overlap area two rectangle
 double OverlapArea( CRtRect<T>& in);

private:
 //conversion the rectangle to polygon
 void Conversion()
 {
  CRtPoint<T> point[4];
  point[0] = mvo_data;
  point[1].SetData( mvo_data[0], mvo_data[1] + mvo_height );  
  point[2].SetData( mvo_data[0] + mvo_width, mvo_data[1] + mvo_height );
  point[3].SetData( mvo_data[0] + mvo_width, mvo_data[1] );
 
  
  CRtPolygon<T>::SetData(4,point);
 }

private:
 CRtPoint< T > mvo_data;//the rectangle top-left point
 T             mvo_width;//the rectangle width
 T             mvo_height;//the rectangle height
};

/******************************************************************************   
the relation a point and rectangle
 If the point in rectangle: return 0
 If the point in rectangle edge: return 1
 If the point is outside the rectangle: return 2
*******************************************************************************/ 
template< class T>
int CRtRect< T >::RelationPoint( CRtPoint<T>& in )
{
 if ( in[0] > mvo_data[0] && in[0] < (mvo_data[0] + mvo_width) &&
      in[1] > mvo_data[1] && in[1] < (mvo_data[1] + mvo_height) ) return 0;
 if ( in[0] < mvo_data[0] || in[0] > (mvo_data[0] + mvo_width) ||
   in[1] < mvo_data[1] && in[1] < (mvo_data[1] + mvo_height) ) return 2;

 return 1;
}

/******************************************************************************   
Assume that the rectangle is expressed by a pair of points (minx, miny) (maxx, maxy)
Then the two rectangles rect1 ((minx1, miny1) (maxx1, maxy1)), rect2 ((minx2, miny2) (maxx2, maxy2))

 Result of the intersection must be a rectangle, constitute the intersection rectangle rect ((minx, miny) (maxx, maxy)) of the coordinates of the points are:
 minx = max (minx1, minx2)
 miny = max (miny1, miny2)
 maxx = min (maxx1, maxx2)
 maxy = min (maxy1, maxy2)

 If the two rectangles do not intersect, then the calculated coordinates of the points necessary to meet the
 minx> maxx
 Either
 miny> maxy

 To determine whether the intersection, as well as what is the intersection rectangle can be calculated using this method to complete one
 The results from this algorithm, we can also generate a simple two out of the following content:

 1 intersect the rectangle: (minx, miny) (maxx, maxy)

 2 Area: area calculation can be found together

 if (minx> maxx) return 0;

 if (miny> maxy) return 0;

 return (maxx-minx) * (maxy-miny)
*******************************************************************************/
template< class T>
double CRtRect< T >::OverlapArea( CRtRect<T>& in)

 int minx = (int)max(mvo_data[0], in.mvo_data[0]); 
 int maxx = min( mvo_data[0] + mvo_width, in.mvo_data[0] + in.mvo_width );
 int miny = (int)max(mvo_data[0], in.mvo_data[1]); 
 int maxy = min(mvo_data[0] + mvo_height, in.mvo_data[1] + in.mvo_height );
 
 return ( minx > maxx || miny > maxy ) ? 0 : ( maxx - minx ) * ( maxy - miny );
}
#endif // !defined(AFX_RTRECT_H__9063CA03_F523_475A_A7E7_C6405A9C5D00__INCLUDED_)

發佈了32 篇原創文章 · 獲贊 1 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章