多边形基类,主要包括:面积、与点的关系、与向量的关系、与直线的关系、与多边形的关系及其各种的交点。
// 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_)