一、设计思路
1.新建一个Function.h文件,在其中声明二维坐标结构体、角度转换函数、方位角计算函数、两点间距离计算函数和三个定点交会函数,并在新建一个Function.cpp文件对函数进行定义(Function.cpp文件中要加入#include "Function.h");
2.在CExercise_4Dlg.cpp文件头处添加 #include "Function.h"
3.计算按钮消息响应函数对交会定点计算函数的调用:
iMethod==1,调用前方交会函数;
iMethod==2,调用测边交会函数;
iMethod==3,调用后方交会函数。
二、主要代码
// function.h : 头文件
#pragma once
struct Point2D //定义二维坐标结构体
{
double X;
double Y;
};
double Dms_TO_Rad(double dDms); //度分秒转化为弧度制
double Distance(struct Point2D &A,struct Point2D &B); //计算两点间的距离
double Azimuth(struct Point2D &A,struct Point2D &B); //计算方位角
struct Point2D ForwardIntersection(struct Point2D &A,struct Point2D &B,double Alpha,double Betta);
//前方交会定点计算
struct Point2D LinearIntersection(struct Point2D &A,struct Point2D &B,double Dap,double Dbp);
//测边交会定点计算
struct Point2D ResctionIntersection(struct Point2D &A,struct Point2D &B,struct Point2D &C,double Alpha,double Betta,double Gamma);
//后方交会定点计算
// function.cpp : 实现文件
#include "StdAfx.h"
#include "Function.h"
#include "math.h"
const double PI=4.0*atan(1.0);
double Dms_TO_Rad(double dDms)
{
double dRad;
int iDegree,iMin;
double dSec;
iDegree=int(dDms);
iMin=int((dDms-iDegree)*100);
dSec=((dDms-iDegree)*100-iMin)*100;
dDms=iDegree+double(iMin)/60+dSec/3600;
dRad=dDms/180*PI;
return dRad;
}
double Distance(struct Point2D &A,struct Point2D &B)
{
double dDistance=0;
dDistance=sqrt((A.X-B.X)*(A.X-B.X)+(A.Y-B.Y)*(A.Y-B.Y));
return dDistance;
}
double Azimuth(struct Point2D &A,struct Point2D &B)
{
// TODO: 在此添加控件通知处理程序代码
double dAzimuth=0; //方位角
double dx=B.X-A.X; //X坐标增量
double dy=B.Y-A.Y; //Y坐标增量
if (dx>0)
{
if (dy>0)
{
dAzimuth=atan(dy/dx);
}
else if(dy<0)
{
dAzimuth=atan(dy/dx)+PI*2;
}
else
dAzimuth=0;
}
else if (dx<0)
{
if(dy>0)
{
dAzimuth=atan(dy/dx)+PI;
}
else if(dy<0)
{
dAzimuth=atan(dy/dx)+PI;
}
else
dAzimuth=PI;
}
else
{
if(dy>0)
dAzimuth=PI/2;
else if(dy<0)
dAzimuth=3*PI/2;
}
return dAzimuth;
}
struct Point2D ForwardIntersection(struct Point2D &A,struct Point2D &B,double Alpha,double Betta)
{
struct Point2D P;
//将度分秒转化为弧度制
double dA=Dms_TO_Rad(Alpha);
double dB=Dms_TO_Rad(Betta);
//计算A,B角余切值
double dCotA=1/tan(dA);
double dCotB=1/tan(dB);
//计算前方交会定位值
P.X=((A.X*dCotB+B.X*dCotA)+(B.Y-A.Y))/(dCotA+dCotB);
P.Y=((A.Y*dCotB+B.Y*dCotA)+(A.X-B.X))/(dCotA+dCotB);
return P;
}
struct Point2D LinearIntersection(struct Point2D &A,struct Point2D &B,double Dap,double Dbp)
{
struct Point2D P;
double Dab; //三角形AB边长
Dab=Distance(A,B);
double alpha_ab; //三角形AB方位角
alpha_ab=Azimuth(A,B);
double Angle_A; //三角形内角A
Angle_A=acos((Dab*Dab+Dap*Dap-Dbp*Dbp)/(2*Dab*Dap));
double alpha_ap=alpha_ab-Angle_A;
P.X=A.X+Dap*cos(alpha_ap);
P.Y=A.Y+Dap*sin(alpha_ap);
return P;
}
struct Point2D ResctionIntersection(struct Point2D &A,struct Point2D &B,struct Point2D &C,double Alpha,double Betta,double Gamma)
{
struct Point2D P;
double dA; //三角形内角A
double dB; //三角形内角B
double dC; //三角形内角C
double a; //三角形边长a
double b; //三角形边长b
double c; //三角形边长c
a=Distance(C,B);
b=Distance(C,A);
c=Distance(B,A);
dA=acos((b*b+c*c-a*a)/(2*b*c));
dB=acos((a*a+c*c-b*b)/(2*a*c));
dC=acos((b*b+a*a-c*c)/(2*b*a));
double C_TEMP; //定义判断是否在危险圆附近的判断变量
double B_TEMP;
double A_TEMP;
C_TEMP=Alpha+Betta+dC;
B_TEMP=Alpha+Gamma+dB;
A_TEMP=Betta+Gamma+dA;
if ((C_TEMP>170)&&C_TEMP<190||
(B_TEMP>170)&&B_TEMP<190||
(B_TEMP>170)&&B_TEMP<190)
{
P.X=-1;
P.Y=-1;
return P; //坐标是(-1,-1)则在危险圆附近
}
double Alpha_Rad=Dms_TO_Rad(Alpha); //度分秒转化为弧度
double Betta_Rad=Dms_TO_Rad(Betta);
double Gamma_Rad=Dms_TO_Rad(Gamma);
double pa=(tan(Alpha_Rad)*tan(dA))/(tan(Alpha_Rad)-tan(dA));
double pb=(tan(Betta_Rad)*tan(dB))/(tan(Betta_Rad)-tan(dB));
double pc=(tan(Gamma_Rad)*tan(dC))/(tan(Gamma_Rad)-tan(dC));
P.X=(pa*A.X+pb*B.X+pc*C.X)/(pa+pb+pc);
P.Y=(pa*A.Y+pb*B.Y+pc*C.Y)/(pa+pb+pc);
return P;
}
// Exercise_4Dlg.h : 头文件
// CExercise_4Dlg 对话框
class CExercise_4Dlg : public CDialog
{
public:
//前方交会控件变量
double dXA_F;
double dYA_F;
double dXB_F;
double dYB_F;
double dAlpha_F;
double dBetta_F;
double dXP_F;
double dYP_F;
//测边交会控件变量
double dXA_L;
double dYA_L;
double dXB_L;
double dYB_L;
double dDap_L;
double dDbp_L;
double dXP_L;
double dYP_L;
//后方交会空间变量
double dXA_R;
double dYA_R;
double dXB_R;
double dYB_R;
double dXC_R;
double dYC_R;
double dXP_R;
double dYP_R;
double dAlpha_R;
double dBetta_R;
double dGamma_R;
int iMethod; //交会定点类型代号
afx_msg void OnBnClickedBtnCal(); //计算按钮
afx_msg void OnBnClickedBtnClear(); //重置编辑框数据
afx_msg void OnBnClickedCancel(); //退出对话框
void ForwardIntersection(double XA,double YA,double XB,double YB,double Alpha,double Betta,double &XP,double &YP);
//前方交会定点计算
void LinearIntersection(double XA,double YA,double XB,double YB,double Dap,double Dbp,double &XP,double &YP);
//测边交会定点计算
void ResctionIntersection(double XA,double YA,double XB,double YB,double XC,double YC,double Alpha,double Betta,double Gamma,double &XP,double &YP);
//后方交会定点计算
};
// Exercise_4Dlg.cpp : 实现文件
#include "stdafx.h"
#include "Exercise_4.h"
#include "Exercise_4Dlg.h"
#include "Function.h"
CExercise_4Dlg::CExercise_4Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CExercise_4Dlg::IDD, pParent)
, dXA_F(116.942) //构造函数中给定变量初始值
, dYA_F(683.295)
, dXB_F(522.909)
, dYB_F(794.647)
, dAlpha_F(59.1042)
, dBetta_F(56.3254)
, dXP_F(398.151)
, dYP_F(413.249)
, dXA_L(1807.041)
, dYA_L(719.853)
, dXB_L(1646.382)
, dYB_L(830.660)
, dDap_L(105.983)
, dDbp_L(159.648)
, dXP_L(1805.957)
, dYP_L(825.830)
, dXA_R(840.134)
, dYA_R(844.422)
, dXB_R(1001.542)
, dYB_R(1620.616)
, dXC_R(659.191)
, dYC_R(1282.629)
, dXP_R(503.702)
, dYP_R(1500.075)
, dAlpha_R(-68.0237)
, dBetta_R(-8.2414)
, dGamma_R(76.2651)
, iMethod(1)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CExercise_4Dlg::OnBnClickedBtnCal()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
struct Point2D A,B,C,P;
//定义个二维结构体变量存放A,B,C,P坐标
if (iMethod==1)
{
A.X=dXA_F;
A.Y=dYA_F;
B.X=dXB_F;
B.Y=dYB_F;
P=ForwardIntersection(A,B,dAlpha_F,dBetta_F);
//调用前方交会定点计算函数
dXP_F=P.X;
dYP_F=P.Y;
}
else if (iMethod==2)
{
A.X=dXA_L;
A.Y=dYA_L;
B.X=dXB_L;
B.Y=dYB_L;
P=LinearIntersection(A,B,dDap_L,dDbp_L);
//调用测边交会定点计算函数
dXP_L=P.X;
dYP_L=P.Y;
}
else if (iMethod==3)
{
A.X=dXA_R;
A.Y=dYA_R;
B.X=dXB_R;
B.Y=dYB_R;
C.X=dXC_R;
C.Y=dYC_R;
P=ResctionIntersection(A,B,C,dAlpha_R,dBetta_R,dGamma_R);
//调用后方交会定点计算函数
dXP_R=P.X;
dYP_R=P.Y;
if ((dXP_R==-1)&&(dXP_R=-1))
{
MessageBox(_T("在危险圆附近"));
}
}
else
MessageBox(_T("代号输入有误"));
UpdateData(FALSE);
}
三、运行结果