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

📄 bachdlg.cpp

📁 摄影测量专业。实现单像后方交会以及立体像对的前方交会。以文件形式读取控制点和像点坐标。
💻 CPP
字号:
// BachDlg.cpp : 实现文件
//
/************************************************************************/
/* 调试很辛苦,尤其是由于这个矩阵类的特性,在MFC中不能直接显示其中的数据
   所以还得在Win32控制台下调试,用矩阵类中的PrintStdout()方法			*/
/************************************************************************/

#include "stdafx.h"
#include "BacAndFor.h"
#include "BachDlg.h"


// BachDlg 对话框

IMPLEMENT_DYNAMIC(BachDlg, CDialog)

BachDlg::BachDlg(CWnd* pParent /*=NULL*/)
	: CDialog(BachDlg::IDD, pParent)
{
	dXs=0;				//外方位元素增量初值
	dYs=0;
	dZs=0;
	dphi=0;
	domega=0;
	dkappa=0;

	phi=-1.6;			//外方位角元素初值
	omega=1.0;
	kappa=1.6;

	Xs=920;				//外方位线元素初值
	Ys=1300;
	Zs=1400;

	f=24.22;

	statusPic=FALSE;	//默认文件读取状态为假
	statusCon=FALSE;

}

BachDlg::~BachDlg()
{
}

void BachDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(BachDlg, CDialog)
	ON_BN_CLICKED(IDC_BUTTON_LOAD_PIC, &BachDlg::OnBnClickedButtonLoadPic)
	ON_BN_CLICKED(IDC_BUTTON_LOAD_CONTROL, &BachDlg::OnBnClickedButtonLoadControl)
	ON_BN_CLICKED(IDC_BUTTON_BACKCAL, &BachDlg::OnBnClickedButtonBackcal)
	ON_BN_CLICKED(IDC_BUTTON_SAVERES, &BachDlg::OnBnClickedButtonSaveres)
END_MESSAGE_MAP()


// BachDlg 消息处理程序

void BachDlg::OnBnClickedButtonLoadPic()
{
	CFileDialog fileDlg(TRUE);				// 打开文件对话框
	fileDlg.m_ofn.lpstrTitle="打开像点坐标文件";		//命名对话框标题
	fileDlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0All Files\0(*.*)\0*.*\0\0";
	if (IDOK==fileDlg.DoModal())
	{
		statusPic=p_Pic.ReadFromFile(fileDlg.GetPathName());	//得到文件路径及文件名并读取文件,成功与否赋值给statusPic
		p=p_Pic;
	}

	if (statusPic)
	{
		MessageBox("文件读取成功!");
	}
	else
	{
		MessageBox("文件读取不成功!");
	}

}

void BachDlg::OnBnClickedButtonLoadControl()
{
	CFileDialog fileDlg(TRUE);				// 打开文件对话框
	fileDlg.m_ofn.lpstrTitle="打开控制点坐标文件";		//命名对话框标题
	fileDlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0All Files\0(*.*)\0*.*\0\0";
	if (IDOK==fileDlg.DoModal())
	{
		statusCon=p_Con.ReadFromFile(fileDlg.GetPathName());	//得到文件路径及文件名并读取文件,成功与否赋值给statusPic
		P=p_Con;
	}

	if (statusCon)
	{
		MessageBox("文件读取成功!");
		ptNum=p_Con.GetNrRows();									//计算点的个数

	}
	else
	{
		MessageBox("文件读取不成功!");
	}

}

void BachDlg::OnBnClickedButtonBackcal()
{
	if (statusCon&statusPic)						//确保坐标点文件读取以防异常
	{
		int m=0;									//迭代次数
		unsigned a,b;
		double v;								//三个角元素中的最大值v,及它的行列号a,b
		Matrix Res_Angle;						//提取三个角元素
		
		do
		{
			LeastCal();
			Res.ExtractSubMatrix(Res_Angle,3,0,5,0);//提取三个角元素
			Res_Angle.GetStats_MaxAbs(a,b,v);		//得到三个角元素中的最大值v,及它的行列号a,b
			m++;									//迭代次数加一
	
		}while(v>=0.01/206265);					// 迭代停止条件为最大的角元素小于0.01秒
	
		Rad2Dms();								//调用此函数的到角值的字符串
		
		CString str0;										//显示结果在编辑框内
		str0.Format("%d",m);
		CString str1;
		str1.Format("%.6f",Xs);
		CString str2;
		str2.Format("%.6f",Ys);
		CString str3;
		str3.Format("%.6f",Zs);
/*		CString str4;
		str4.Format("%.6f",phi);
		CString str5;
		str5.Format("%.6f",omega);
		CString str6;
		str6.Format("%.6f",kappa);
*/	
		
		out="迭代次数:"+str0+"\r\nXs: "+str1+"\r\nYs: "+str2+"\r\nZs: "+str3+"\r\nφ: "+strPhi+ "\r\nω: "+strOmega+"\r\nκ: "+strKappa;
	
		GetDlgItem(IDC_EDIT_SHOW_BK)->SetWindowText(out);
	} 

	else
	{
		MessageBox("文件读取不成功!");

	}
}

void BachDlg::CreateR()
{
	
	Matrix R(3,3);									//旋转阵
	Matrix R1(3,3);									//旋转阵分量
	Matrix R2(3,3);									//cos(phi)=11 sin(phi)=22 cos(omega)=33 sin(omega)=44  cos(kap)=55 sin(kappa)=66
	Matrix R3(3,3);
	R1="[11 0 -22;0 1 0;22 0 11]";					//不能直接像matlab那样为矩阵赋值,
	R2="[1 0 0;0 33 -44;0 44 33]";					//有需要sin,cos运算的地方先随便用个数代替,然后逐一赋值
	R3="[55 -66 0;66 55 0;0 0 1]";

	R1(0,0)=cos(phi);
	R1(0,2)=-sin(phi);
	R1(2,0)=sin(phi);
	R1(2,2)=cos(phi);

	R2(1,1)=cos(omega);
	R2(1,2)=-sin(omega);
	R2(2,1)=sin(omega);
	R2(2,2)=cos(omega);

	R3(0,0)=cos(kappa);
	R3(0,1)=-sin(kappa);
	R3(1,0)=sin(kappa);
	R3(1,1)=cos(kappa);


	R=R1*R2*R3;

	a1=R[0][0];
	a2=R[0][1];
	a3=R[0][2];

	b1=R[1][0];
	b2=R[1][1];
	b3=R[1][2];

	c1=R[2][0];
	c2=R[2][1];
	c3=R[2][2];

	R_G=R;
}

void BachDlg::CreateLum()
{
	int i;
	Matrix Lum_L(3*ptNum,1);
	Matrix temp;
	Matrix Ps(3,1);							//形成[Xs;Ys;Zs]这样的矩阵
	Ps(0,0)=Xs;
	Ps(1,0)=Ys;
	Ps(2,0)=Zs;

	for (i=1;i<=ptNum;i++)
	{
		Matrix P_Sub;
		P.ExtractSubMatrix(P_Sub,i-1,1,i-1,3);		//将控制点P的子矩阵(即第i个点的坐标)赋给P_Sub
		P_Sub=P_Sub.T()-Ps;							//形成这样的矩阵
		temp=R_G.T()*P_Sub;							//temp为当前点 R'*[X-Xs;Y-Ys;Z-Zs]结果
		Lum_L.InsertSubMatrix(temp,3*i-3,0);		//将所有点行成的Xbar,Ybar,Zbar累加在一起
	}	

	Lum=Lum_L;
//	Lum.PrintStdout();

}


/************************************************************************/
/* 此处特别注意,矩阵中某元素拿来运算时必须用[]引用,而不能用() 。
   例如Lum[3*i-1]不能写成Lum(3*i-1),吃了大亏!
/************************************************************************/
void BachDlg::CreateB()
{
	int i;
	Matrix B(2*ptNum,6);
	double x,y;                            //像点坐标,局部变量,便于创建B矩阵
	for (i=1;i<=ptNum;i++)
	{
		x=p[i-1][1];
	    y=p[i-1][2];

		B(2*i-2,0)=1/Lum[3*i-1]*(a1*f+a3*x);
		B(2*i-2,1)=1/Lum[3*i-1]*(b1*f+b3*x);
		B(2*i-2,2)=1/Lum[3*i-1]*(c1*f+c3*x);
		B(2*i-2,3)=y*sin(omega)-(x/f*(x*cos(kappa)-y*sin(kappa))+f*cos(kappa))*cos(omega);
		B(2*i-2,4)=-f*sin(kappa)-x/f*(x*sin(kappa)+y*cos(kappa));
		B(2*i-2,5)=y;

		B(2*i-1,0)=1/Lum[3*i-1]*(a2*f+a3*y);
		B(2*i-1,1)=1/Lum[3*i-1]*(b2*f+b3*y);
		B(2*i-1,2)=1/Lum[3*i-1]*(c2*f+c3*y);
		B(2*i-1,3)=-x*sin(omega)-(y/f*(x*cos(kappa)-y*sin(kappa))-f*sin(kappa))*cos(omega);
		B(2*i-1,4)=-f*cos(kappa)-y/f*(x*sin(kappa)+y*cos(kappa));
		B(2*i-1,5)=-x;
	}
	Bcl=B;
}

void BachDlg::CreateL()
{
	Matrix l(2*ptNum,1);
	double x,y;

	for (int i=1;i<=ptNum;i++)
	{		
		x=p[i-1][1];
		y=p[i-1][2];

		l(2*i-2,0)=f*Lum[3*i-3]/Lum[3*i-1]+x;
		l(2*i-1,0)=f*Lum[3*i-2]/Lum[3*i-1]+y;
	}
	
	lcl=l;
}

void BachDlg::LeastCal()
{
	CreateR();								// 创建旋转阵
	CreateLum();							//Xbar Ybar Zbar
	CreateB();                              //创建参数系数阵
	CreateL();                              //创建l阵

	
	Res=(Bcl.T()*Bcl).Inv()*Bcl.T()*lcl;	//解法方程
	dXs=Res[0];
	dYs=Res[1];
	dZs=Res[2];
	dphi=Res[3];
	domega=Res[4];
	dkappa=Res[5];

	Xs=Xs+dXs;
	Ys=Ys+dYs;
	Zs=Zs+dZs;
	phi=phi+dphi;
	omega=omega+domega;
	kappa=kappa+dkappa;
}

void BachDlg::Rad2Dms()
{
	double TT=acos(-1.0);							//Pi
	Deg_Phi=int(phi*180/TT);
	Min_Phi=int((phi*180/TT-Deg_Phi)*60);
	Sec_Phi=(((phi*180/TT-Deg_Phi)*60-Min_Phi)*60);
	
	Deg_Omega=int(omega*180/TT);
	Min_Omega=int((omega*180/TT-Deg_Omega)*60);
	Sec_Omega=(((omega*180/TT-Deg_Omega)*60-Min_Omega)*60);
	
	Deg_Kappa=int(kappa*180/TT);
	Min_Kappa=int((kappa*180/TT-Deg_Kappa)*60);
	Sec_Kappa=(((kappa*180/TT-Deg_Kappa)*60-Min_Kappa)*60);




	Min_Phi=abs(Min_Phi);
	Sec_Phi=abs(Sec_Phi);
	
	Min_Omega=abs(Min_Omega);
	Sec_Omega=abs(Sec_Omega);

	Min_Kappa=abs(Min_Kappa);
	Sec_Kappa=abs(Sec_Kappa);

	if (Sec_Phi==60.0)                 //解决分秒为60的问题
	{
		Sec_Phi=.0;
		Min_Phi+=1;
	}
	if (Min_Phi==60)
	{
		Min_Phi=0;
		if (Deg_Phi>=0)
		{
			Deg_Phi+=1;
		}
		else Deg_Phi-=1;
	}

	if (Sec_Omega==60.0)
	{
		Sec_Omega=.0;
		Min_Omega+=1;
	}
	if (Min_Omega==60)
	{
		Min_Omega=0;
		if (Deg_Omega>=0)
		{
			Deg_Omega+=1;
		}
		Deg_Omega-=1;
	}

	if (Sec_Kappa==60.0)                
	{
		Sec_Kappa=.0;
		Min_Kappa+=1;
	}
	if (Min_Kappa==60)
	{
		Min_Kappa=0;
		if (Deg_Kappa>=0)
		{
			Deg_Kappa+=1;
		}
		else Deg_Kappa-=1;
	}



	//b1=(char)B1+"°"+(char)B2+"'"+(char)B3+"'";
	//l1=L1+"°"+L2+"'"+L3+"'";
	CString c;
	
	strPhi.Format("%d",Deg_Phi);				//以字符串形式的Phi,Omega,Kappa
	strPhi+="°";
	c.Format(" %d",Min_Phi);
	strPhi+=c;
	strPhi+="′";
	c.Format(" %.6f",Sec_Phi);
	strPhi+=c;
	strPhi+="″";


	strOmega.Format("%d",Deg_Omega);
	strOmega+="°";
	c.Format(" %d",Min_Omega);
	strOmega+=c;
	strOmega+="′";
	c.Format(" %.6f",Sec_Omega);
	strOmega+=c;
	strOmega+="″";

	strKappa.Format("%d",Deg_Kappa);
	strKappa+="°";
	c.Format(" %d",Min_Kappa);
	strKappa+=c;
	strKappa+="′";
	c.Format(" %.6f",Sec_Kappa);
	strKappa+=c;
	strKappa+="″";
}


void BachDlg::OnBnClickedButtonSaveres()
{
	CFileDialog fileDlg(FALSE);				// 打开文件对话框
	fileDlg.m_ofn.lpstrTitle="保存外方位元素文件";		//命名对话框标题
	fileDlg.m_ofn.lpstrFilter="Text File(*.txt)\0*.txt\0All Files\0(*.*)\0*.*\0\0";
	fileDlg.m_ofn.lpstrDefExt="txt";
	if (IDOK==fileDlg.DoModal())
	{
		CFile file(fileDlg.GetFileName(),CFile::modeCreate|CFile::modeWrite);	//创建一个文件,以写入方式打开
		file.Write(out,(UINT)out.GetLength());									//将结果写入到文件
		file.Close();
	}

}

⌨️ 快捷键说明

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