提供點的基本運算(加、減、乘、Euclidean距離),同時是後面向量、直線、多邊形的基礎。
#ifndef ROBOT_THINKING_GEOM_DEFINE_WANGFEI_INCLUDE_20091118
#define ROBOT_THINKING_GEOM_DEFINE_WANGFEI_INCLUDE_20091118
//the minimum error
#ifndef MINERR
#define MINERR 1E-10
#endif
#ifndef PI
#define PI 3.1415926f
#endif
#ifndef INF
#define INF 1E200
#endif
#ifndef EPSILON
#define EPSILON 0.001f
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif //ROBOT_THINKING_GEOM_DEFINE_WANGFEI_INCLUDE_20091118
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_RTPOINT_H__C8107570_647C_4728_8C75_2F7C5D56BED2__INCLUDED_)
#define AFX_RTPOINT_H__C8107570_647C_4728_8C75_2F7C5D56BED2__INCLUDED_
#include "define.h"
template<class T, int dim = 2 >
class CRtPoint
{
public:
//Default constructor, defined for template classes
CRtPoint(): mvi_dim(dim)
{
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
}
virtual ~CRtPoint()
{
delete []mvo_pData;
mvo_pData = NULL;
}
//constructor
CRtPoint( T* data ): mvi_dim(dim)
{
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
memcpy( mvo_pData, data, sizeof(T)* mvi_dim );
}
//2 dimension
CRtPoint( T x, T y ): mvi_dim(dim)
{
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
*mvo_pData = x;
*( mvo_pData + 1 ) = y;
}
//3 dimension
CRtPoint( T x, T y, T z ): mvi_dim(dim)
{
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
*mvo_pData = x;
*( mvo_pData + 1 ) = y;
*( mvo_pData + 2 ) = z;
}
//copy constructor
CRtPoint( const CRtPoint& in )
{
mvi_dim = in.mvi_dim;
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
memcpy( mvo_pData, in.mvo_pData, sizeof(T)* mvi_dim );
}
//operators overload:
//Accumulative addition of two vectors
CRtPoint& operator += (const CRtPoint& in )
{
for( int i = 0; i < mvi_dim; i++ )
*(mvo_pData + i) += *(in.mvo_pData + i);
return *this;
}
// Accumulative subtraction of two vectors
CRtPoint& operator -= (const CRtPoint& in )
{
for( int i = 0; i < mvi_dim; i++ )
*(mvo_pData + i) -= *(in.mvo_pData + i);
return *this;
}
// Accumulative multiplication of a point by a scalar
CRtPoint& operator *= (const CRtPoint& in )
{
for( int i = 0; i < mvi_dim; i++ )
*(mvo_pData + i) *= *(in.mvo_pData + i);
return *this;
}
CRtPoint& operator *= (const double& in )
{
for( int i = 0; i < mvi_dim; i++ )
*(mvo_pData + i) *= in;
return *this;
}
//Vector Equality, epsilon used due to numerical imprecision
bool operator == (const CRtPoint& in )
{
if( fabs( mvi_dim - in.mvi_dim) < EPSILON )
{
for( int i = 0; i < mvi_dim; i++ )
if( fabs ( *(mvo_pData + i) - *(in.mvo_pData + i) ) > EPSILON ) break;
return true;
}
return false;
}
//evaluate to point
const CRtPoint& operator = (const CRtPoint& in)
{
mvi_dim = in.mvi_dim;
delete []mvo_pData;
mvo_pData = NULL;
mvo_pData = new T[mvi_dim];
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
memcpy( mvo_pData, in.mvo_pData, sizeof(T)* mvi_dim );
return *this;
}
//get a element
T operator [] (const int index)
{
return *(mvo_pData + index);
}
//Reassign a point without making a temporary structure
void SetData( T* data)
{
memset( mvo_pData, 0x00, sizeof(T)* mvi_dim );
memcpy( mvo_pData, data, sizeof(T)* mvi_dim );
}
void SetData( T x, T y)
{
if ( mvi_dim != 2 ) return;
*mvo_pData = x;
*( mvo_pData + 1 ) = y;
}
//return a point to user
T* GetData()const
{
return mvo_pData;
}
int GetDim()const
{
return mvi_dim;
}
//Euclidean distance: d =sqrt( ∑(xi1-xi2)^ ) ,i=1,2..n
double DistEuclidean(CRtPoint& in)
{
double val = 0;
for( int i = 0; i< mvi_dim; i++ )
val += pow( *( in.mvo_pData + i) - *(mvo_pData + i), 2);
return sqrt(val);
}
/******************************************************************************
Cross Product Mode:
Unit vector of the mode is 1, the available cross product of the modulus:
Cross product of a very important property can be judged by its symbol between the two vectors
of cis-anti-clockwise relationship:
P = (x1,y1) ,Q = (x2,y2),P × Q = x1*y2 - x2*y1,
If the OP × OQ > 0, then OP in the OQ in a clockwise direction.
If the OP × OQ < 0, then OP in the OQ of the counter-clockwise.
If the OP × OQ = 0, then OP and OQ collinear, but may in the same direction may reverse.
*******************************************************************************/
T CrossProductMode( CRtPoint<T, dim>& in)
{
if (2 == dim) return in[0] * mvo_pData[1] - in[1] * mvo_pData[0];
if (3 == dim) return in[1] * mvo_pData[2] + in[2] * mvo_pData[0] + in[0] * mvo_pData[1]
- in[2] * mvo_pData[1] + in[0] * mvo_pData[2] + in[1] * mvo_pData[0];
}
private:
int mvi_dim;//dimension
T* mvo_pData;//point data
};
//Adds two points together
template<class T, int dim>
inline const CRtPoint<T, dim> operator + (const CRtPoint<T, dim>& src0, const CRtPoint<T, dim>& src1)
{
return CRtPoint<T,dim>(src0) += src1;
}
//Subtracts to points
template<class T, int dim>
inline const CRtPoint<T, dim> operator - (const CRtPoint<T, dim>& src0, const CRtPoint<T, dim>& src1)
{
return CRtPoint<T,dim>(src0) -= src1;
}
//multiplication of a point by a scalar
template<class T, int dim>
inline const CRtPoint<T, dim> operator * (const CRtPoint<T, dim>& src0, const CRtPoint<T, dim>& src1)
{
return CRtPoint<T,dim>(src0) *= src1;
}
#endif // !defined(AFX_RTPOINT_H__C8107570_647C_4728_8C75_2F7C5D56BED2__INCLUDED_)