几何中点(三维向量)、线、面的类

来源:互联网 发布:linux 磁盘挂载重启 编辑:程序博客网 时间:2024/05/21 06:59

AssPoint.h

 

// 版权所有(C) 梁意, 2004

// 最后修改: 2004.6.杭州

 

#ifndef AssPoint_HEADER

#define AssPoint_HEADER

 

#include<cmath>

#include<limits>

#include<vector>

#include<deque>

#include<iostream>

 

//#define Container vector

#define Container deque

 

using namespace std;

 

#define PI 3.1415926535897932384626 //M_PI

 

#define ASS_DELTA 1e-6 //or FLT_EPSILON (1.192092896e-07F)  or  DBL_EPSILON in float.h

 

 

template

class AssPoint

{

public:

 typedef AssPoint _Myt;

 AssPoint()//构造函数,原点

 {

  X=0;

  Y=0;

  Z=0;

 }

 AssPoint(T _X,T _Y,T _Z=0)//构造函数,X,Y,Z

 {

  X=_X;

  Y=_Y;

  Z=_Z;

 }

 AssPoint(const _Myt &P)//构造函数,X,Y,Z

 {

  X=P.X;

  Y=P.Y;

  Z=P.Z;

 }

 bool operator == ( _Myt & P) //比较两点是否相等,坐标误差DELTA

 {

  return(fabs(X-P.X) }

 _Myt operator -( _Myt & P)//两点相减

 {

  return _Myt(X-P.X,Y-P.Y,Z-P.Z);

 }

 _Myt operator +( _Myt & P)//两点相加

 {

  return _Myt(X+P.X,Y+P.Y,Z+P.Z);

 }

 _Myt operator -( T  d)//三方向同时减去d

 {

  return _Myt(X-d,Y-d,Z-d);

 }

 _Myt operator +( T d)//三方向同时加上d

 {

  return _Myt(X+d,Y+d,Z+d);

 }

 _Myt operator *( T d)//三方向同时乘上d

 {

  return _Myt(X*d,Y*d,Z*d);

 }

 _Myt operator /( T d)//三方向同时除以d

 {

  return _Myt(X/d,Y/d,Z/d);

 }

 T operator *( _Myt & P)//点积

 {

  return X*P.X+Y*P.Y+Z*P.Z;

 }

 T Dis( _Myt &P)//到另一点的距离

 {

  return sqrt(pow(X-P.X,2)+pow(Y-P.Y,2)+pow(Z-P.Z,2));

 }

 _Myt _X( _Myt &P)//叉积

 {

  return _Myt(Y*P.Z-Z*P.Y,Z*P.X-X*P.Z,X*P.Y-Y*P.X);

 }

 T Modul()//求模

 {

  return sqrt( (*this) * (* this) );

 }

 bool HasTheSameDirection( _Myt & _P)//向量是否方向相同

 {

  return (_P/_P.Modul())==((*this)/Modul());

 }

 bool IsNearPt( _Myt & _P,T _dis)//是否在_P附近

 {

  return Dis( _P )<=fabs(_dis);

 }

 _Myt Scale(T Sx,T Sy,T Sz, _Myt &BasePoint=_Myt() )//BasePoint为基点,三方向分别缩放Sx,Sy,Sz

 {

  _Myt tmp=(*this)-BasePoint;

  return _Myt(tmp.X*Sx,tmp.Y*Sy,tmp.Z*Sz)+BasePoint;

 }

 _Myt Transfrom(T tx,T ty,T tz )//移动tx,ty,tz

 {

  return _Myt(X+tx,Y+ty,Z+tz);

 }

 T AngleYZ()//YZ面夹角

 {

  return asin(X/Modul());

 }

 T AngleZX()//ZX面夹角

 {

  return asin(Y/Modul());

 }

 T AngleXY()//XY面夹角

 {

  return asin(Z/Modul());

 }

 T AngleX_XY()//XY面的投影与X轴正向的夹角

 {

  if(Y>=0)

   return acos(X/sqrt(pow(X,2)+pow(Y,2)));

  return PI*2.0-acos(X/sqrt(pow(X,2)+pow(Y,2)));

 }

 T AngleY_XY()//XY面的投影与Y轴正向的夹角

 {

  if(X<=0)

   return acos(Y/sqrt(pow(X,2)+pow(Y,2)));

  return PI*2.0-acos(Y/sqrt(pow(X,2)+pow(Y,2)));

 }

 T AngleY_YZ()//YZ面的投影与Y轴正向的夹角

 {

  if(Z>=0)

   return acos(Y/sqrt(pow(Y,2)+pow(Z,2)));

  return PI*2.0-acos(Y/sqrt(pow(Y,2)+pow(Z,2)));

 }

 T AngleZ_YZ()//YZ面的投影与Z轴正向的夹角

 {

  if(Y<=0)

   return acos(Z/sqrt(pow(Y,2)+pow(Z,2)));

  return PI*2.0-acos(Z/sqrt(pow(Y,2)+pow(Z,2)));

 }

 T AngleZ_ZX()//ZX面的投影与Z轴正向的夹角

 {

  if(X>=0)

   return acos(Z/sqrt(pow(Z,2)+pow(X,2)));

  return PI*2.0-acos(Z/sqrt(pow(Z,2)+pow(X,2)));

 }

 T AngleX_ZX()//ZX面的投影与X轴正向的夹角

 {

  if(Z<=0)

   return acos(X/sqrt(pow(Z,2)+pow(X,2)));

  return PI*2.0-acos(X/sqrt(pow(Z,2)+pow(X,2)));

 }

 _Myt RotateX(T ceta)//X轴旋转ceta

 {

  return( _Myt( X,Y*cos(ceta)-Z*sin(ceta),Z*cos(ceta)+Y*sin(ceta) ) );

 }

 _Myt RotateY(T ceta)//Y轴旋转ceta

 {

  return( _Myt( X*cos(ceta)+Z*sin(ceta) ,Y ,Z*cos(ceta)-X*sin(ceta) ) );

 }

 _Myt RotateZ(T ceta)//Z轴旋转ceta

 {

  return( _Myt( X*cos(ceta)-Y*sin(ceta) ,Y*cos(ceta)+X*sin(ceta),Z) );

 }

 T Angle( _Myt &other)//与另一向量的夹角

 {

  return acos( (*this)*other/this->Modul()/other.Modul() );

 }

 _Myt Rotate(T ceta, _Myt &Dir)//绕一原点为起点方向为Dir的轴旋转ceta

 {

  T a=-Dir.AngleZ_YZ();

  T b=-Dir.AngleYZ();

  return RotateX(a).RotateY(b).RotateZ(ceta).RotateY(-b).RotateX(-a);

 }

 T X;

 T Y;

 T Z;

};

 

#endif

 

AssLine.h

 

// 版权所有(C) 梁意, 2004

// 最后修改: 2004.6.杭州

 

 

 

#ifndef AssLine_HEADER

#define AssLine_HEADER

 

#include"AssPoint.h"

 

template

class AssLine

{

public:

 enum Input_type

 {

  Point_Slope,

  TwoPoints

 };

 typedef AssPoint _MyPoint;

 typedef AssLine  _Myt;

 

 AssLine()//两点一线

 { 

 }

 AssLine(const _Myt &other)//两点一线

 {

  P1=other.P1;

  P2=other.P2;

 }

 AssLine(_MyPoint & _P1,_MyPoint & _P2)//两点一线

 {

  P1=_P1;

  P2=_P2; 

 }

 AssLine(_MyPoint &P,T A,T B,T C,Input_type type=_Myt::Point_Slope)

 {

  if(type==_Myt::Point_Slope)

  {

   P2=_MyPoint(P.X+A,P.Y+B,P.Z+C);

  }

  if(type==_Myt::TwoPoints)

  {

   P2=_MyPoint(A,B,C);

  }

  P1=P;

 }

 AssLine(T X,T Y,T Z,T X2,T Y2,T Z2)//两点一线

 {

  P1=_MyPoint(X,Y,Z);

  P2=_MyPoint(X2,Y2,Z2);

 }

 _Myt & operator =( const _Myt &other)

 {

  P1=other.P1;

  P2=other.P2;

  return (*this);

 }

 T GetLength()//返回长度

 {

  return sqrt(pow(P1.X-P2.X,2)+pow(P1.Y-P2.Y,2)+pow(P1.Z-P2.Z,2));

 }

 T AngleX()//X轴夹角

 {

  return acos( (P2-P1).X/(P2-P1).Modul() );

 }

 T AngleY()//Y轴夹角

 {

  return acos( (P2-P1).Y/(P2-P1).Modul() );

 }

 T AngleZ()//Z轴夹角

 {

  return acos( (P2-P1).Z/(P2-P1).Modul() );

 }

 T AngleXY()//XY面夹角

 {

  return (P2-P1).AngleXY();

 }

 T AngleZX()//ZX面夹角

 {

  return (P2-P1).AngleZX();

 }

 T AngleYZ()//YZ面夹角

 {

  return (P2-P1).AngleYZ();

 }

 bool IsLine()//长度太小就不是线,DELTA控制

 {

  return GetLength()>=ASS_DELTA;

 }

 bool operator == (_Myt & _L)//两条线是否重合

 {

  return (*this || _L) && IsOnLine(_L.P1);

 }

 bool IsOnLine(_MyPoint &P)//点是否在线上

 {

  return (P-P1).HasTheSameDirection(P2-P1);

 }

 bool IsInLineSegment(_MyPoint &P)//点是否在线段内

 {

  return IsOnLine(P) && ( (P-P1).HasTheSameDirection(P2-P) );

 }

 T Angle(AssLine & _L)//与另一线的夹角

 {

  return acos( (P2-P1)*(_L.P2-_L.P1)/( (P2-P1).Modul() * (_L.P2-_L.P1).Modul() ) );

 }

 bool IsPerpendicular(_Myt & _L)//是否与另一线垂直

 {

  return (P2-P1)*(_L.P2-_L.P1)< ASS_DELTA;

 }

 bool operator || (_Myt & _L)//是否与另一线平行

 {

  _MyPoint tmp1=P2-P1;

  _MyPoint tmp2=_L.P2-_L.P1;

  return ((tmp1/tmp1.Modul())._X(tmp2/tmp2.Modul())).Modul() }

 _Myt ParallelLine(_MyPoint & P)//过点的平行线

 {

  return  _Myt(P,P2-P1+P);

 }

 _Myt PerpendicularLine(_MyPoint &P)//过点的垂线

 {

  return _Myt(P,(P2-P1) * ( (P-P1)*(P2-P1)/pow((P2-P1).Modul(),2) ) + P1 );

 }

 T Dis(_MyPoint & P)//到点的距离

 {

  return (P-P1)._X(P2-P1).Modul()/(P2-P1).Modul();

 }

 T Dis(_Myt & _L)//到线的距离

 {

  _MyPoint P=(P2-P1)._X(_L.P2-_L.P1);

  return fabs((P1-_L.P1)*P)/P.Modul();

 }

 _MyPoint Intersection(_Myt & _L)//与线的交点

 {

  if( Dis(_L)>ASS_DELTA ) return _MyPoint( DBL_MAX,0);

  _MyPoint _tmp1(P2-P1);

  _MyPoint _tmp2(_L.P2-_L.P1);

  _MyPoint _tmp4=_tmp1._X(_tmp2)._X( _tmp2 );

  _MyPoint _tmp5=_L.P1-P1;

  T t= (_tmp4*_tmp5)/(_tmp4*_tmp1);

  return  ( P1+( _tmp1*t) );

 }

 _Myt PerpendicularLine( AssLine & _L)//同时与另一线垂直的线

 {

  if( ( (*this) || _L ) ) return _Myt(0,0,0,DBL_MAX,DBL_MAX,DBL_MAX);

  _MyPoint _tmp1(P2-P1);

  _MyPoint _tmp2(_L.P2-_L.P1);

  _MyPoint _tmp3=_tmp1._X(_tmp2);

  _MyPoint _tmp4=_tmp3._X(_tmp2);

  _MyPoint _tmp5=_L.P1-P1;

  T t= (_tmp4*_tmp5)/(_tmp4*_tmp1);

  return _Myt(P1+( _tmp1*t),P1+( _tmp1*t)+_tmp3);

 }

 bool IsNearPt(_MyPoint & _P,T _dis)//是否在离线_dis距离内

 {

  return Dis( _P )<=fabs(_dis) ;

 }

 void GetNDivide( Container< _MyPoint > & Points,size_t n)//n等分点

 {

  Points.clear();

//  if(n<=0) return;

  if(n==1)

  {

   Points.push_back(P1);

   Points.push_back(P2);

   return;

  }

  T tmp_stepX=(P2.X-P1.X)/((T)n);

  T tmp_stepY=(P2.Y-P1.Y)/((T)n);

  T tmp_stepZ=(P2.Z-P1.Z)/((T)n);

  for(int i=0;i<=n;i++)

  {

   Points.push_back(P1+ ( _MyPoint(tmp_stepX,tmp_stepY,tmp_stepZ)*((T)i)) );

  }

 }

 _MyPoint Rotate(_MyPoint P,T ceta)//旋转

 {

  return (P-P1).Rotate(ceta,P2-P1)+P1;

 }

 

 _MyPoint P1,P2;

};

 

#endif

 

AssPlane.h

 

// 版权所有(C) 梁意, 2004

// 最后修改: 2004.6.杭州

 

 

 

#ifndef AssPlane_HEADER

#define AssPlane_HEADER

 

 

#include"AssLine.h"

 

template

class AssPlane

{

public:

 typedef AssPoint _MyPoint;

 typedef AssLine  _MyLine;

 typedef AssPlane _Myt;

 

 AssPlane()//默认构造函数,方向(1,1,1),过原点的平面

 {

  A=1;

  B=1;

  C=1;

 }

 AssPlane(const _Myt &other)

 {

  A=other.A;

  B=other.B;

  C=other.C;

  P=other.P;

 }

 AssPlane(T _A,T _B,T _C,_MyPoint & _P=_MyPoint() )//方向(_A,_B,_C),过点_P的平面

 {

  A=_A;

  B=_B;

  C=_C;

  P=_P;

 }

 AssPlane(_MyPoint & vector,_MyPoint _P=_MyPoint() )//方向vector,过点_P的平面

 {

  A=vector.X ;

  B=vector.Y;

  C=vector.Z;

  P=_P;

 }

 AssPlane(_MyPoint &P1,_MyPoint &P2,_MyPoint &P3)//3点的平面

 {

  _MyPoint tmp1=P2-P1;

  _MyPoint tmp2=P3-P1;

  _MyPoint tmp3=tmp1._X(tmp2);

  A=tmp3.X;

  B=tmp3.Y;

  C=tmp3.Z;

  P=P1;

 }

 AssPlane(_MyLine  &_L,_MyPoint &_P)//过点和线的平面

 {

  _MyPoint tmp1=_L.P1-_P;

  _MyPoint tmp2=_L.P2-_P;

  _MyPoint tmp3=tmp1._X(tmp2);

  A=tmp3.X;

  B=tmp3.Y;

  C=tmp3.Z;

  P=_P;

 }

 _MyLine  PerpendicularLine(_MyPoint & _P)//过点_P与面垂直的线

 {

  return _MyLine(_P,A,B,C,_MyLine::Point_Slope);

 }

 _Myt ParallelPlane(_MyPoint & _P)//过点与面平行的平面

 {

  return _Myt(A,B,C,_P);

 }

 T Dis(_MyPoint & _P)//面到点距离

 {

  _MyPoint _tmp1(A,B,C);

  return fabs( _tmp1*( _P-P ) )/_tmp1.Modul();

 }

 T Dis(_Myt & _PL)//面到面的距离

 {

  _MyPoint _tmp1(A,B,C);

  _MyPoint _tmp2(_PL.A,_PL.B,_PL.C);

  _MyPoint _tmp3=_tmp1._X(_tmp2);

  if(_tmp3.Modul()>ASS_DELTA) return 0;

  return Dis( _PL.P );

 }

 _Myt PerpendicularPlane(_MyLine  & _L)//过线与面垂直的面

 {

  _MyPoint _tmp1=_L.P2-_L.P1;

  _MyPoint _tmp2=_tmp1._X(_MyPoint(A,B,C));

  return _Myt(_tmp2.X,_tmp2.Y,_tmp2.Z,_L.P1);

 }

 _Myt ParallelPlane(_MyLine  & _L)//过线与面平行的面

 {

  if( ! ( (*this) || _L ) ) return AssPlane(0,0,0,Point(0,0,0));

  return _Myt(A,B,C,_L.P1);

 }

 _MyPoint Intersection(_MyLine  &_L)//面与线交点

 {

  if( (*this) || _L ) return _MyPoint(DBL_MAX,DBL_MAX,DBL_MAX);

  _MyPoint _tmp1=_L.P2-_L.P1;

  _MyPoint _tmp2=P- _L.P1;

  _MyPoint _tmp3(A,B,C);

  return ( _tmp1* ( ( _tmp3*_tmp2 )/( _tmp3*_tmp1) ) ) + _L.P1;

 }

 bool operator || (_MyLine  & _L)//与线平行判断

 {

  return fabs( (_L.P2-_L.P1)*_MyPoint(A,B,C) )  }

 bool operator || (_Myt & _PL)//与面平行判断

 {

  _MyPoint _tmp1(A,B,C);

  _MyPoint _tmp2(_PL.A,_PL.B,_PL.C);

  return ((_tmp1/_tmp1.Modul())._X(_tmp2/_tmp2.Modul())).Modul() }

 T Angle(_MyLine  & _L)//面与线的夹角

 {

  _MyPoint _tmp1=_L.P2-_L.P1;

  _MyPoint _tmp2(A,B,C);

  return acos( _tmp1*_tmp2 /( _tmp1.Modul()* _tmp2.Modul() ) );

 }

 T Angle(_Myt & _PL)//与面的夹角

 {

  _MyPoint _tmp1(A,B,C);

  _MyPoint _tmp2(_PL.A,_PL.B,_PL.C);

  return acos( (_tmp1 * _tmp2 )/( _tmp1.Modul() *_tmp2.Modul() ) );

 }

 _MyLine  Intersection(AssPlane & _PL)//面与面的交

 {

  if( (*this) || _PL ) return _MyLine (0,0,0,0,0,0);

  _MyPoint _tmp1(A,B,C);

  _MyPoint _tmp2(_PL.A,_PL.B,_PL.C);

  _MyPoint _tmp3=_tmp1._X(_tmp2);

  _MyLine _tmpL1(_PL.P,_PL.P+_tmp3._X(_tmp2));

  _MyLine _tmpL2(P,P+_tmp3._X(_tmp1));

  if(_tmpL1.Dis(_tmpL2)   return _MyLine(_tmpL1.Intersection(_tmpL2),_tmp3.X,_tmp3.Y,_tmp3.Z,_MyLine::Point_Slope);

  return _tmpL1.PerpendicularLine(_tmpL2);

 }

 bool IsInPlane(_MyPoint &_P)//点在平面内判断

 {

  return fabs((_P-P)*_MyPoint(A,B,C)) }

 bool IsInPlane(_MyLine  &_L)//线在平面内判断

 {

  return IsInPlane(_L.P1) && IsInPlane(_L.P2);

 }

 _MyPoint GetNormal()//单位方向

 {

  _MyPoint _tmp(A,B,C);

  return _tmp/_tmp.Modul();

 }

 bool IsNearPt(_MyPoint & _P,T _dis)//是否在离面_dis距离内

 {

  return Dis( _P )<=fabs(_dis) ;

 }

 _Myt Offset(T _h)//偏移_h得到的平面

 {

  _MyPoint tmpP(A,B,C);

  T t=_h/tmpP.Modul();

  return _Myt(A,B,C,P+(_MyPoint(A,B,C)*t));

 }

 T A,B,C;

 _MyPoint  P;

};

 

 

 

#endif

 

原创粉丝点击