计算几何算法四:多边形

多边形基类,主要包括:面积、与点的关系、与向量的关系、与直线的关系、与多边形的关系及其各种的交点。

// RtPolygon.h: interface for the CRtPolygon class.
//
//

#if !defined(AFX_RTPOLYGON_H__F53D55ED_B6EC_4605_B2DB_D5643BA9CAF4__INCLUDED_)
#define AFX_RTPOLYGON_H__F53D55ED_B6EC_4605_B2DB_D5643BA9CAF4__INCLUDED_

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

#include "RtPoint.h"

template<class T>
class CRtPolygon
{
public:
 //constructor
 CRtPolygon(): mvi_num(3), mvi_numNode(0)
 {
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  mvo_node = new CRtPoint<double>[mvi_num * 2];
 }
 CRtPolygon( int num ): mvi_num( num ), mvi_numNode(0)
 {
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  mvo_node = new CRtPoint<double>[mvi_num * 2];
 }
 CRtPolygon( int num, const CRtPoint* in ): mvi_num( num )
 {
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  mvo_node = new CRtPoint<double>[mvi_num * 2];
  for ( int i = 0; i< mvi_num; i++ )
   *( mvo_data + i) = *( in + i );
 }

 //copy constructor
 CRtPolygon( const CRtPolygon& in )
 {
  delete[] mvo_data;
  mvo_data = NULL;
  delete[] mvo_node;
  mvo_node = NULL;

  mvi_num = in.mvi_num;
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  mvo_node = new CRtPoint<T>[mvi_num * 2];

  for ( int i = 0; i< mvi_num; i++ )
   *( mvo_data + i) = *( in + i );
 }

 //destructor
 virtual ~CRtPolygon()
 {
  delete[] mvo_data;
  mvo_data = NULL;
  
  delete[] mvo_node;
  mvo_node = NULL;

  mvi_num = 0;
 }

//operators overload:
 //Polygon Equality, epsilon used due to numerical imprecision
 bool operator == ( const CRtPolygon& in )
 {
  if (mvi_num == in.mvi_num)
  {
   for (int i= 0; i < mvi_num; i++ )
    if (in.mvo_data[i] != mvo_data[i] ) return false;

   return true;
  }

  return false;
 }

 //evaluate to polygon
 CRtPolygon& operator = ( const CRtPolygon& in )
 {
  delete[] mvo_data;
  mvo_data = NULL;
  delete[] mvo_node;
  mvo_node = NULL;
  
  mvi_num = in.mvi_num;
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  mvo_node = new CRtPoint<T>[mvi_num * 2];

  for ( int i = 0; i< mvi_num; i++ )
   *( mvo_data + i) = *( in.mvo_data + i );
  
  return *this;
 }

 //area
 virtual double Area();

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

 //the relation a vector and polygon
 virtual int RelationVector( CRtVector<T>& in);

 //the relation a line and polygon
 virtual int RelationLine( CRtLine<T>& in);

 //the relation a polygon
 virtual int RalationPolygon( CRtPolygon<T>& in );

 //get interset point data
 int GetIntersectNum() const
 {
  return mvi_numNode;
 }

 int GetInsersect( int index, CRtPoint<T>& out)
 {
  if (index > mvi_num - 1 && index < 0) return -1;
  
  out  = *( mvo_node + index );
  
  return 0;
 }
 //set point
 void SetData( const int num , const CRtPoint<T>* data)
 {
  delete[] mvo_data;
  mvo_data = NULL;
  
  mvi_num = num;
  mvo_data = new CRtPoint<T>[mvi_num * 2];
  
  for ( int i = 0; i< mvi_num; i++ )
   *( mvo_data + i) = *( data + i );
 }

private:
 int       mvi_num;//the point num
 CRtPoint<T>* mvo_data;//the points

 CRtPoint<double>* mvo_node;//the interset which is line/(line segments) and rectanle interset point
 int       mvi_numNode;//the interset point number
};

/********************************************************************************************   
Ray method to determine the relationship between the location of points and polygons require
a simple polygon polygon, vertices ordered counterclockwise
If the point in polygon: return 0
If the point in polygon edge: return 1
If the point is outside the polygon: return 2
*********************************************************************************************/
template<class T>
int CRtPolygon<T>::RelationPoint( CRtPoint<T>& in)

 int count = 0; 
 CRtVector<T> vector1,vector2;  
 CRtPoint<T> point( (T)1E5, in[1] );
 vector1.SetData(in,point);
 for ( int i = 0; i < mvi_num; i++ ) 
 { 
  vector2.SetData( *(mvo_data + i), *(mvo_data + ( i + 1 ) % mvi_num ) );
  if ( vector2.RelationPoint(in)) return 1;
  if ( vector1.IsIntersect(vector2) ) count++; 
 } 
 
 return count % 2 == 1 ? 0 : 2;
}

/******************************************************************************   
the relation a vector and polygon:
a vector in polygon when two points of vector in polygon
a vector and polygon intersect when a points of vector in polygon and other outside the polygon or int rectangle polygon or ...
a vector is outside the polygon when two points of vector outside rectangle

 If the vector in polygon: return 0
 If the vector and polygon intersect: return 1
 If the vector is outside the polygon: return 2
*******************************************************************************/
template<class T>
int CRtPolygon<T>::RelationVector( CRtVector<T>& in)
{
 mvi_numNode = 0;
 
 int val = 2;
 bool relat0 = RelationPoint(in[0]) == 0;
 bool relat1 = RelationPoint(in[1]) == 0;
 
 if( relat0 || relat1 ) val = 1; 
 if( relat0 && relat1 ) val = 0;

 if (val != 0)
 { 
  CRtVector<T> vector;
  for ( int i = 0; i < mvi_num; i++ )
  {
   vector.SetData( *(mvo_data + i), *(mvo_data + (i + 1) % mvi_num ) );    
   if ( vector.Intersect(in, mvo_node[mvi_numNode] ) ) mvi_numNode++;
  }
  
  if (mvi_numNode > 0) val = 1;
 }
 
 return val;
}

/******************************************************************************   
the relation a line and polygon:
 If a line and polygon intersect: return 1
 If a line is outside the polygon: return 2
*******************************************************************************/
template<class T>
int CRtPolygon<T>::RelationLine( CRtLine<T>& in)
{
 mvi_numNode = 0;
 
 CRtVector<T> vector;  
 for ( int i = 0; i < mvi_num; i++ )
 {
  vector.SetData( *(mvo_data + i), *(mvo_data + (i + 1) % mvi_num ) );   
  if ( in.Intersect(vector, mvo_node[mvi_numNode] ) ) mvi_numNode++;
 }
 
 return mvi_numNode > 0 ? 1 : 2;
}

/******************************************************************************   
the relation a polygon and polygon:
 If the polygon in polygon: return 0
 If the polygon and polygon intersect: return 1
 If the polygon is outside the polygon: return 2
*******************************************************************************/
template<class T>
int CRtPolygon<T>::RalationPolygon( CRtPolygon<T>& in )

 int count = 0, val = 1;
 for ( int i = 0; i < mvi_num; i++ )
  if ( RelationPoint( *(in.mvo_data + i) ) ) count++;

 if ( count == mvi_num )  val = 0;
 if ( count == 0 ) val = 2;

 return val;
}

//area
template<class T>
double CRtPolygon<T>::Area()
{
 double area = 0;
 area = (*mvo_data)[1] * ( ( *(mvo_data + mvi_num - 1) )[0] - ( *(mvo_data + 1) )[0] ); 
 for ( int i=1; i < mvi_num; i++)
  area += ( *(mvo_data + i) )[1] * ( ( *(mvo_data + i - 1) )[0] - ( *(mvo_data + (i + 1) % mvi_num) )[0] );
 
 return area/2;
}

#endif // !defined(AFX_RTPOLYGON_H__F53D55ED_B6EC_4605_B2DB_D5643BA9CAF4__INCLUDED_)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值