計算幾何算法一:點

提供點的基本運算(加、減、乘、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_)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章