?? dyx_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 + -