⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dyx_point.cpp

📁 这里提供一套C++的point定义类,里面有丰富的成员函数,全部通过验证。同时也望朋友们对其进行扩充和改进
💻 CPP
字号:
#include "StdAfx.h"
#include <math.h>
#include "DYX_Point.h"
#include "DYX_Vector.h"
#include "DYX_LineCircle.h"
#include "DYX_Math.h"
#include "DYX_MeshDefinition.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif



//-------------------------------------
//	Implementation of Class Point2D 
//-------------------------------------

void Point2D::operator=(const Point2D &P)
{
	this->x = P.x;
	this->y = P.y;
}


BOOL Point2D::operator==(const Point2D &P) const
{
	if(fabs(this->x-P.x) < MEAN_ERR && fabs(this->y-P.y) < MEAN_ERR)
		return TRUE;
	else
		return FALSE;
}


BOOL Point2D::operator!=(const Point2D &P) const
{
	if(fabs(this->x-P.x) >= MEAN_ERR || fabs(this->y-P.y) >= MEAN_ERR)
		return TRUE;
	else
		return FALSE;
}


Point2D Point2D::operator+(const Point2D &P) const
{
	Point2D Pt;
	
	Pt.x = this->x + P.x;
	Pt.y = this->y + P.y;

	return Pt;
}


Point2D Point2D::operator-(const Point2D &P) const
{
	Point2D Pt;
	
	Pt.x = this->x - P.x;
	Pt.y = this->y - P.y;

	return Pt;
}


void Point2D::SetPoint(const double x1, const double y1)
{
	this->x = x1;
	this->y = y1;
}


void Point2D::SetPoint(const double Pt[2])
{
	this->x = Pt[0];
	this->y = Pt[1];
}


void Point2D::SetPoint(const Point2D Pt)
{
	this->x = Pt.x;
	this->y = Pt.y;
}


double Point2D::Multiply(const Point2D &P, const Point2D &Q) const
{ 
//	r = Multiply(P,Q), 得到(P-O)*(Q-O)的叉积 
//	r>0 : Q在矢量OP的逆时针方向; 
//	r=0 : op->P->Q 三点共线; 
//	r<0 : Q在矢量OP的顺时针方向 

	return ((P.x-this->x)*(Q.y-this->y)-(Q.x-this->x)*(P.y-this->y)); 
} 


double Point2D::dotMultiply(const Point2D &P, const Point2D &Q) const
{ 
// ---------------------------------------------------------------------------
//	O为当前点,r=dotMultiply(P,Q),得到矢量(P-O)和(Q-O)的点积,如果两个矢量都非零矢量 
//	r<0:两矢量夹角为锐角;
//	r=0:两矢量夹角为直角;
//	r>0:两矢量夹角为钝角 
//------------------------------------------------------------------------------ 

	return ((P.x-this->x)*(Q.x-this->x)+(P.y-this->y)*(Q.y-this->y)); 
} 


void Point2D::Move(const double x1, const double y1)
{
	this->x += x1;
	this->y += y1;
}


double Point2D::Distance(const Point2D &P) const
{
//	返回两点之间欧氏距离 
	
	return sqrt((P.x-this->x)*(P.x-this->x)+(P.y-this->y)*(P.y-this->y)); 
}


double Point2D::Distance(const LineSeg2D &L) const
{ 
//	求当前点到线段L所在直线的最短距离

	return fabs(L.sp.Multiply(*this, L.ep)) / L.Distance(); 
} 



void Point2D::Rotate(const Point2D &RotateCenter, const double dAngle)
{ 
//	返回当前点以点Cent为圆心逆时针旋转dAngle(单位:弧度)后所在的位置

	double x1 = this->x - RotateCenter.x; 
	double y1 = this->y - RotateCenter.y; 

	this->x = x1*cos(dAngle) - y1*sin(dAngle) + RotateCenter.x; 
	this->y = y1*cos(dAngle) + x1*sin(dAngle) + RotateCenter.y; 
} 


BOOL Point2D::IsEqualTo(const Point2D &P, const double Tol) const
{ 
//	判断两个点是否重合  

	return ( (fabs(P.x-this->x) < Tol) && (fabs(P.y-this->y) < Tol) ); 
} 


BOOL Point2D::OnLineSeg(const LineSeg2D &L) const
{ 
//	设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 
//	且 Q 在以 P1,P2为对角顶点的矩形内。前者保证Q点在直线P1P2上,
//	后者是保证Q点不在线段P1P2的延长线或反向延长线上。
 
	return ( fabs(Multiply(L.sp, L.ep)) < EPS && 
			 (this->x-L.sp.x)*(this->x-L.ep.x) <= 0.0 && 
			 (this->y-L.sp.y)*(this->y-L.ep.y) <= 0.0 ); 
} 



double Point2D::Angle(const Point2D &B) const
{
//	返回顶角在当前点A,终点在B的有向线段与X轴正向的夹角。
//	角度小于PI,返回正值 
//	角度大于PI,返回负值 

	Vector2D Vt(B.x-this->x, B.y-this->y); 
	return Vt.Angle();
} 



double Point2D::Angle(const Point2D &B, const Point2D &C) const
{
//	返回顶角在当前点A,起始边为AB,终止边为AC的夹角(单位:弧度) 
//	角度小于PI,返回正值 
//	角度大于PI,返回负值 
//
//	可以用于求线段之间的夹角 
//
//	We define the angle theta between two vectors v and w by the formula
//                      v . w           
//        cos Q  =  --------------               
//                    ||v|| ||w|| 
//	so that
//         v . w = ||v|| ||w|| cos Q

	double x1 = B.x - this->x; 
	double y1 = B.y - this->y; 
	double x2 = C.x - this->x; 
	double y2 = C.y - this->y; 

	double cosAngle = x1*x2 + y1*y2; 
	double norm = (x1*x1+y1*y1) * (x2*x2+y2*y2); 
	cosAngle /= sqrt( norm ); 

	if (cosAngle >=  1.0-EPS ) 
		return 0.0; 
	if (cosAngle <= -1.0+EPS ) 
		return PI; 

	double dAngle = acos(cosAngle); 
	if (x1*y2-y1*x2 < 0.0)
		return (-dAngle);		// 说明矢量AO->BO为顺时针方向 
	else						// 说明矢量AO->BO为逆时针方向 
		return dAngle; 
} 


double Point2D::TriangleAngle(const Point2D &B, const Point2D &C) const
{
//	三角形余玄定理:a^2=b^2+c^2-2bcCOS(Angle)。
//	a, b, c为边长,Angle为BC两条线间的夹角。
//	返回值在0->PI之间。

	double a2 = (B.x-C.x)*(B.x-C.x) + (B.y-C.y)*(B.y-C.y);
	double b2 = (this->x-C.x)*(this->x-C.x) + (this->y-C.y)*(this->y-C.y);
	double c2 = (this->x-B.x)*(this->x-B.x) + (this->y-B.y)*(this->y-B.y);

	if(a2 < MEAN_ERR || b2 < MEAN_ERR || c2 < MEAN_ERR)
	{
		::AfxMessageBox(_T("The three points are colliear."));
		return 0.0;
	}

	double cosAngle = (b2+c2-a2) / (2.0*sqrt(b2*c2));
	if(cosAngle >= 1.0-EPS)
		return 0.0;
	else if(cosAngle <= EPS-1.0)
		return PI;
	else
		return acos(cosAngle);
}


double Point2D::TriangleArea(const Point2D &B, const Point2D &C) const
{
//	To obtain the directional area of triangle.
//	area > 0.0 if A->B->C are counter-clockwise; 
//	area < 0.0 if A->B->C are clockwise;
//	area == 0 if A, B and C are colliear.

	return (0.5*((B.x-this->x)*(C.y-this->y) - (C.x-this->x)*(B.y-this->y)));
}



double Point2D::Relation(const LineSeg2D &L) const
{
//	本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足 
//
//                AC dot AB 
//        r =     --------- 
//                 ||AB||^2 
//
//             (Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay) 
//          = ------------------------------- 
//                          L^2 
//
//    r has the following meaning: 
//
//        r=0		P = A 
//        r=1		P = B 
//        r<0		P is on the backward extension of AB 
//		  r>1		P is on the forward extension of AB 
//        0<r<1		P is interior to AB 

	double dot = L.sp.dotMultiply(*this, L.ep);
	double dist = L.Distance();

	return dot / (dist*dist); 
} 


Point2D Point2D::Perpendicular(const LineSeg2D &L) const
{ 
// 求点C到线段AB所在直线的垂足 P 

	double r = this->Relation(L); 

	Point2D tmpPt; 

	tmpPt.x = L.sp.x + r*(L.ep.x-L.sp.x); 
	tmpPt.y = L.sp.y + r*(L.ep.y-L.sp.y); 

	return tmpPt; 
} 


double Point2D::NearestDistance(const LineSeg2D &L, Point2D &P) const
{ 
// -------------------------------------------------
//	求当前点到线段L的最短距离,并返回线段上距该点最近的点Pt 
//	注意:Pt是线段L上到当前点最近的点,不一定是垂足
//----------------------------------------------------
	double r = this->Relation(L); 
	if(r < 0.0) 
	{ 
		P = L.sp; 
		return this->Distance(L.sp); 
	} 
	if(r > 1.0) 
	{ 
		P = L.ep; 
		return this->Distance(L.ep); 
	} 

	P = this->Perpendicular(L); 
	return this->Distance(P); 
} 
 

void Point2D::TangentialPoint(const Circle2D &Cir, Point2D &P1, Point2D &P2) const
{ 
//  求通过当前点到给定圆的切点。 
//	p---圆心坐标, r---圆半径, sp---圆外一点, Pt1,Pt2---切点坐标 

	Circle2D tmpCir;

	tmpCir.x = (Cir.x+this->x) / 2.0; 
	tmpCir.y = (Cir.y+this->y) / 2.0; 

	double dx2 = tmpCir.x-Cir.x; 
	double dy2 = tmpCir.y-Cir.y; 

	tmpCir.r = sqrt(dx2*dx2+dy2*dy2); 

	tmpCir.Intersect(Cir, P1, P2); 
}


 
Point2D Point2D::Symmetry(const Line2D &L) const
{ 
// 求当前点关于直线L的对称点 

	Point2D tmpPt; 
	
	tmpPt.x=((L.b*L.b-L.a*L.a)*x-2*L.a*L.b*y-2*L.a*L.c)/(L.a*L.a+L.b*L.b); 
	tmpPt.y=((L.a*L.a-L.b*L.b)*y-2*L.a*L.b*x-2*L.b*L.c)/(L.a*L.a+L.b*L.b); 
	
	return tmpPt; 
}


BOOL Point2D::Inside(const Circle2D &Cir) const
{ 
//	当前点在圆内(包括边界)时,返回true 
	
	double d2 = (this->x-Cir.x)*(this->x-Cir.x)+(this->y-Cir.y)*(this->y-Cir.y); 
	double r2 = Cir.r*Cir.r;

	if(d2 <= r2)
		return TRUE;
	else
		return FALSE;
}


BOOL Point2D::Inside(const MyRectangle &Rect, const double dGap) const
{
//	当前点在矩形内部(包括边界)时,返回true 

	MyRectangle tmpRect(Rect);
	Point2D tmpPt(*this);

	double rotAngle = -tmpRect.RotateAngle;
	if(fabs(rotAngle) > EPS)
	{
		tmpRect.Rotate(tmpRect.LowLeft, rotAngle);
		tmpPt.Rotate(tmpRect.LowLeft, rotAngle);
	}

	double x1 = tmpRect.LowLeft.x + dGap;
	double y1 = tmpRect.LowLeft.y + dGap;
	double x2 = tmpRect.LowLeft.x + tmpRect.Width - dGap;
	double y2 = tmpRect.LowLeft.y + tmpRect.Length - dGap;

	if( x1 <= tmpPt.x && tmpPt.x <= x2 &&
		y1 <= tmpPt.y && tmpPt.y <= y2 )
		return TRUE;
	else
		return FALSE;
}



//-------------------------------------
//	Implementation of Class Point3D 
//-------------------------------------
void Point3D::operator=(const Point3D &P)
{
	this->x = P.x;
	this->y = P.y;
	this->z = P.z;
}


BOOL Point3D::operator==(const Point3D &P) const
{
	if( fabs(this->x-P.x) < MEAN_ERR && 
		fabs(this->y-P.y) < MEAN_ERR &&
		fabs(this->z-P.z) < MEAN_ERR )
		return TRUE;
	else
		return FALSE;
}


BOOL Point3D::operator!=(const Point3D &P) const
{
	if( fabs(this->x-P.x) >= MEAN_ERR || 
		fabs(this->y-P.y) >= MEAN_ERR ||
		fabs(this->z-P.z) >= MEAN_ERR )
		return TRUE;
	else
		return FALSE;
}


Point3D Point3D::operator+(const Point3D &P) const
{
	Point3D tmpPt;
	
	tmpPt.x = this->x + P.x;
	tmpPt.y = this->y + P.y;
	tmpPt.z = this->y + P.z;

	return tmpPt;
}


Point3D Point3D::operator-(const Point3D &P) const
{
	Point3D tmpPt;
	
	tmpPt.x = this->x - P.x;
	tmpPt.y = this->y - P.y;
	tmpPt.z = this->z - P.z;

	return tmpPt;
}


void Point3D::SetPoint(const double x1, const double y1, const double z1)
{
	this->x = x1;
	this->y = y1;
	this->z = z1;
}


void Point3D::SetPoint(const double Pt[3])
{
	this->x = Pt[0];
	this->y = Pt[1];
	this->z = Pt[2];
}


double Point3D::Distance(const Point3D &P) const
{
//	返回两点之间欧氏距离 

	return sqrt((P.x-this->x)*(P.x-this->x) + (P.y-this->y)*(P.y-this->y) + (P.z-this->z)*(P.z-this->z)); 
}


void MyTest(void)
{
	Point2D P1(0, 0);
	MyRectangle Rect(P1, 4, 2);

	Point2D P2(-1, 2);
	Circle2D Cir(P2, 0.5);

	BOOL bFlag = Cir.Inside(Rect);

	Rect.Rotate(Rect.LowLeft, 90.0*DEG_To_RAD);
	bFlag = Cir.Inside(Rect);

	Rect.Offset(0.5);

//	TCHAR text[80];
//	_stprintf(text, _T("%lf\t%lf"), inPt.x, inPt.y);
//	str += text;

//	::AfxMessageBox(str);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -