?? bachdlg.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 + -