DLTDlg.cpp
Upload User: szacenet
Upload Date: 2022-06-20
Package Size: 317k
Code Size: 22k
Category:

Graph program

Development Platform:

Visual C++

  1. // DLTDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "DLT.h"
  5. #include "DLTDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAboutDlg dialog used for App About
  13. class CAboutDlg : public CDialog
  14. {
  15. public:
  16. CAboutDlg();
  17. // Dialog Data
  18. //{{AFX_DATA(CAboutDlg)
  19. enum { IDD = IDD_ABOUTBOX };
  20. //}}AFX_DATA
  21. // ClassWizard generated virtual function overrides
  22. //{{AFX_VIRTUAL(CAboutDlg)
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. //}}AFX_VIRTUAL
  26. // Implementation
  27. protected:
  28. //{{AFX_MSG(CAboutDlg)
  29. //}}AFX_MSG
  30. DECLARE_MESSAGE_MAP()
  31. };
  32. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAboutDlg)
  35. //}}AFX_DATA_INIT
  36. }
  37. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. //{{AFX_DATA_MAP(CAboutDlg)
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  44. //{{AFX_MSG_MAP(CAboutDlg)
  45. // No message handlers
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CDLTDlg dialog
  50. CDLTDlg::CDLTDlg(CWnd* pParent /*=NULL*/)
  51. : CDialog(CDLTDlg::IDD, pParent)
  52. {
  53. //{{AFX_DATA_INIT(CDLTDlg)
  54. //}}AFX_DATA_INIT
  55. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  56. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  57. pLeftLi = new double[12];//li系数精确值,k
  58. pRightLi = new double[12];//li系数精确值,k
  59. pLOrient = new double [11];
  60. pROrient = new double [11];
  61. }
  62. void CDLTDlg::DoDataExchange(CDataExchange* pDX)
  63. {
  64. CDialog::DoDataExchange(pDX);
  65. //{{AFX_DATA_MAP(CDLTDlg)
  66. //}}AFX_DATA_MAP
  67. }
  68. BEGIN_MESSAGE_MAP(CDLTDlg, CDialog)
  69. //{{AFX_MSG_MAP(CDLTDlg)
  70. ON_WM_SYSCOMMAND()
  71. ON_WM_PAINT()
  72. ON_WM_QUERYDRAGICON()
  73. ON_BN_CLICKED(IDC_BUTN_CTRL, OnButnCtrl)
  74. ON_BN_CLICKED(IDC_BUTN_LEFT, OnButnLeft)
  75. ON_BN_CLICKED(IDC_BUTN_RIGHT, OnButnRight)
  76. //}}AFX_MSG_MAP
  77. END_MESSAGE_MAP()
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CDLTDlg message handlers
  80. BOOL CDLTDlg::OnInitDialog()
  81. {
  82. CDialog::OnInitDialog();
  83. // Add "About..." menu item to system menu.
  84. // IDM_ABOUTBOX must be in the system command range.
  85. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  86. ASSERT(IDM_ABOUTBOX < 0xF000);
  87. CMenu* pSysMenu = GetSystemMenu(FALSE);
  88. if (pSysMenu != NULL)
  89. {
  90. CString strAboutMenu;
  91. strAboutMenu.LoadString(IDS_ABOUTBOX);
  92. if (!strAboutMenu.IsEmpty())
  93. {
  94. pSysMenu->AppendMenu(MF_SEPARATOR);
  95. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  96. }
  97. }
  98. // Set the icon for this dialog.  The framework does this automatically
  99. //  when the application's main window is not a dialog
  100. SetIcon(m_hIcon, TRUE); // Set big icon
  101. SetIcon(m_hIcon, FALSE); // Set small icon
  102. // TODO: Add extra initialization here
  103. return TRUE;  // return TRUE  unless you set the focus to a control
  104. }
  105. void CDLTDlg::OnSysCommand(UINT nID, LPARAM lParam)
  106. {
  107. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  108. {
  109. CAboutDlg dlgAbout;
  110. dlgAbout.DoModal();
  111. }
  112. else
  113. {
  114. CDialog::OnSysCommand(nID, lParam);
  115. }
  116. }
  117. // If you add a minimize button to your dialog, you will need the code below
  118. //  to draw the icon.  For MFC applications using the document/view model,
  119. //  this is automatically done for you by the framework.
  120. void CDLTDlg::OnPaint() 
  121. {
  122. if (IsIconic())
  123. {
  124. CPaintDC dc(this); // device context for painting
  125. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  126. // Center icon in client rectangle
  127. int cxIcon = GetSystemMetrics(SM_CXICON);
  128. int cyIcon = GetSystemMetrics(SM_CYICON);
  129. CRect rect;
  130. GetClientRect(&rect);
  131. int x = (rect.Width() - cxIcon + 1) / 2;
  132. int y = (rect.Height() - cyIcon + 1) / 2;
  133. // Draw the icon
  134. dc.DrawIcon(x, y, m_hIcon);
  135. }
  136. else
  137. {
  138. CDialog::OnPaint();
  139. }
  140. }
  141. // The system calls this to obtain the cursor to display while the user drags
  142. //  the minimized window.
  143. HCURSOR CDLTDlg::OnQueryDragIcon()
  144. {
  145. return (HCURSOR) m_hIcon;
  146. }
  147. void CDLTDlg::OnOK() 
  148. {
  149. // TODO: Add extra validation here
  150. if (m_CtrlPoints.size()==0 ||m_LeftPoints.size() == 0 || m_RightPoints.size()==0)
  151. {
  152. MessageBox("请先输入数据");
  153. return ;
  154. }
  155. CalXYZAndPrecision(m_LeftPoints,m_RightPoints,pLOrient,pROrient,pLeftLi,pRightLi);
  156. if(ShellExecute(NULL,"open",strResultFileName,NULL,NULL,SW_SHOWNORMAL) < (HANDLE)32)
  157. MessageBox("结果保存在:"+strResultFileName,"TipS",MB_OK|MB_ICONINFORMATION);
  158. //CDialog::OnOK();
  159. }
  160. void CDLTDlg::OnButnLeft() 
  161. {
  162. // TODO: Add your control notification handler code here
  163. if(m_CtrlPoints.size()==0)
  164. {
  165. MessageBox("无控制点数据","ERROR",MB_OK|MB_ICONWARNING);
  166. return;
  167. }
  168. //读取数据
  169. m_LeftPoints.clear();
  170.     CString filename = OpenFileStore(&m_LeftPoints);
  171. if (m_LeftPoints.size()<6)
  172. {
  173. MessageBox("量测像点数目太少,不能计算!","Tips",MB_OK|MB_ICONINFORMATION);
  174. m_LeftPoints.clear();
  175. SetDlgItemText(IDC_BUTN_LEFT,"");
  176. return;
  177. }
  178. SetDlgItemText(IDC_EDIT_LEFT,filename);
  179. //////////////////////////////////////////////////
  180. //计算li系数近似值
  181. FILE *fp;
  182. fp = fopen(strResultFileName,"a+");
  183. double *pLi = new double [11];
  184. if(!CalApproximateLiFactors(m_LeftPoints,m_CtrlPoints,pLi))
  185. {
  186. MessageBox("像点对应的控制点不足6个,无法计算!");
  187. m_LeftPoints.clear();
  188. SetDlgItemText(IDC_BUTN_LEFT,"");
  189. return ;
  190. }
  191. //计算li系数精确值,k和方位元素
  192. int nCnt = CalOrtAndLiFactors(m_LeftPoints,m_CtrlPoints,pLi,pLOrient,pLeftLi);
  193. fprintf(fp,"左片"+filename+"的li系数如下:n     近似值         精确值n");
  194.     for (int i = 0;i<11;i++)
  195.     {
  196. fprintf(fp,"l%d  %.6f   %.6fn",i,pLi[i],pLeftLi[i]);
  197.     }
  198. fprintf(fp,"对称径向畸变系数k:%.6fn迭代次数:%dn",pLeftLi[i],nCnt);
  199. //输出方位元素
  200. CString strFWs[11] ={"x0","y0","fx","ds","dB","Xs","Ys","Zs","t(phi)","w","k"};
  201. for ( i = 0;i<11;i++)
  202.     {
  203. fprintf(fp,"%s  %.6fn",strFWs[i],pLOrient[i]);
  204.     }
  205. fclose(fp);
  206. delete [] pLi;
  207. /////////////////////////
  208. }
  209. void CDLTDlg::OnButnRight() 
  210. {
  211. // TODO: Add your control notification handler code here
  212. if(m_CtrlPoints.size()==0)
  213. {
  214. MessageBox("无控制点数据","ERROR",MB_OK|MB_ICONWARNING);
  215. return;
  216. }
  217. m_RightPoints.clear();
  218.     CString filename = OpenFileStore(&m_RightPoints);
  219. if (m_RightPoints.size()<6)
  220. {
  221. MessageBox("量测像点数目太少,不能计算!","Tips",MB_OK|MB_ICONINFORMATION);
  222. m_RightPoints.clear();
  223. SetDlgItemText(IDC_BUTN_RIGHT,"");
  224. return;
  225. }
  226. SetDlgItemText(IDC_EDIT_RIGHT,filename);
  227. //////////////////////////
  228. FILE *fp;
  229. fp = fopen(strResultFileName,"a+");
  230. double *pLi = new double [11];
  231. if(!CalApproximateLiFactors(m_RightPoints,m_CtrlPoints,pLi))
  232. {
  233. MessageBox("像点对应的控制点不足6个,无法计算!");
  234. m_RightPoints.clear();
  235. SetDlgItemText(IDC_BUTN_LEFT,"");
  236. return ;
  237. }
  238. //计算li系数精确值,k和方位元素
  239. int nCnt = CalOrtAndLiFactors(m_RightPoints,m_CtrlPoints,pLi,pROrient,pRightLi);
  240. fprintf(fp,"右片"+filename+"的li系数如下:n     近似值         精确值n");
  241.     for (int i = 0;i<11;i++)
  242.     {
  243. fprintf(fp,"l%d  %.6f   %.6fn",i,pLi[i],pRightLi[i]);
  244.     }
  245. fprintf(fp,"对称径向畸变系数k:%.6fn迭代次数:%dn",pRightLi[i],nCnt);
  246. //输出方位元素
  247. CString strFWs[11] ={"x0","y0","fx","ds","dB","Xs","Ys","Zs","t(phi)","w","k"};
  248. for ( i = 0;i<11;i++)
  249.     {
  250. fprintf(fp,"%s  %.6fn",strFWs[i],pROrient[i]);
  251.     }
  252. fclose(fp);
  253. delete [] pLi;
  254. /////////////////////////
  255. }
  256. void CDLTDlg::OnButnCtrl() 
  257. {
  258. // TODO: Add your control notification handler code here
  259. m_CtrlPoints.clear();
  260.     CString filename = OpenFileStore(&m_CtrlPoints);
  261. if(filename=="") return ;
  262. if (m_CtrlPoints.size()<6)
  263. {
  264. MessageBox("控制点数目太少,不能计算!","Tips",MB_OK|MB_ICONINFORMATION);
  265. m_CtrlPoints.clear();
  266. SetDlgItemText(IDC_BUTN_CTRL,"");
  267. return;
  268. }
  269. SetDlgItemText(IDC_EDIT_CTRL,filename);
  270. strResultFileName = filename.Left(filename.ReverseFind('\')+1)+"\DLT_Results.txt";
  271. }
  272. CString CDLTDlg::OpenFileStore(vector<PixPoint> * Container )
  273. {
  274.     CString strFilename = "";
  275. Container->clear();
  276. CFileDialog openFile(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"文本文件(*.txt)|*.txt||",NULL);
  277. if (openFile.DoModal()==IDCANCEL)
  278. return "";
  279. strFilename = openFile.GetPathName();
  280. //read data
  281. CStdioFile pInFile;
  282. if (!pInFile.Open(strFilename, CFile::modeRead)) 
  283. return "";
  284. int nNum =0 ;//point order number
  285. double x = 0.0;//  
  286. double y = 0.0;
  287. CString strLine;
  288. while (pInFile.ReadString(strLine))
  289. {
  290. //strLine是一行文本
  291. PixPoint point;
  292. sscanf(strLine,"%d %lf %lf",&nNum,&x,&y);
  293. point.ID = nNum;
  294. point.x = x;//PixPoint(nNum,x,y);
  295. point.y = y;
  296. Container->push_back(point); 
  297. }
  298. pInFile.Close();
  299.     return strFilename;
  300. }
  301. CString CDLTDlg::OpenFileStore(vector<GeodeticPoint> * Container )
  302. {
  303. CString strFilename = "";
  304. Container->clear();
  305. CFileDialog openFile(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"文本文件(*.txt)|*.txt||",NULL);
  306. if (openFile.DoModal()==IDCANCEL)
  307. return "";
  308. strFilename = openFile.GetPathName();
  309. //read data
  310. CStdioFile pInFile;
  311. if (!pInFile.Open(strFilename, CFile::modeRead)) 
  312. return "";
  313. int nNum =0 ;//point order number
  314. double x = 0.0;//  
  315. double y = 0.0;
  316. double z =0.0;
  317. CString strLine;
  318. while (pInFile.ReadString(strLine))
  319. {
  320. //strLine是一行文本
  321. GeodeticPoint point;
  322. sscanf(strLine,"%d %lf %lf %lf",&nNum,&x,&y,&z);
  323. point.ID = nNum;
  324. point.x = x;//GeodeticPoint(nNum,x,y,z);
  325. point.y = y;
  326. point.z = z;
  327. Container->push_back(point); 
  328. }
  329. pInFile.Close();
  330.     return strFilename; 
  331. }
  332. bool CDLTDlg::CalApproximateLiFactors(vector<PixPoint> xPixContner,vector<GeodeticPoint> CtrlContner,double *pPara)
  333. {
  334. //搜索像点对应的控制点
  335.     vector<GeodeticPoint> CalCtrlPts;
  336. vector<PixPoint>PixContner;
  337. for (int i =0;i<xPixContner.size();i++)
  338. {
  339. for(int j = 0;j<CtrlContner.size();j++)
  340. {
  341. if (xPixContner.at(i).ID == CtrlContner.at(j).ID)
  342. {
  343. CalCtrlPts.push_back(CtrlContner.at(j));
  344. PixContner.push_back(xPixContner.at(i));
  345. break;
  346. }
  347. }
  348. }
  349. int nCalPtsNum = CalCtrlPts.size();
  350. if (nCalPtsNum<6)
  351. return false;
  352. //计算li系数的近似解approximate calculation 
  353. double * LiApproA = new double[nCalPtsNum*2*11];
  354. double * LiApproC = new double[nCalPtsNum * 2];
  355. for (i = 0;i<nCalPtsNum;i++)//逐点计算系数
  356. {
  357. LiApproA[22*i + 0] = CalCtrlPts.at(i).x;
  358. LiApproA[22*i + 1] = CalCtrlPts.at(i).y;
  359. LiApproA[22*i + 2] = CalCtrlPts.at(i).z;
  360. LiApproA[22*i + 3] = 1;
  361. LiApproA[22*i + 4] = 0;
  362. LiApproA[22*i + 5] = 0;
  363. LiApproA[22*i + 6] = 0;
  364. LiApproA[22*i + 7] = 0;
  365. LiApproA[22*i + 8] = PixContner.at(i).x * CalCtrlPts.at(i).x;
  366. LiApproA[22*i + 9] = PixContner.at(i).x * CalCtrlPts.at(i).y;
  367. LiApproA[22*i + 10] = PixContner.at(i).x * CalCtrlPts.at(i).z;
  368. LiApproA[22*i + 11] = 0;
  369. LiApproA[22*i + 12] = 0;
  370. LiApproA[22*i + 13] = 0;
  371. LiApproA[22*i + 14] = 0;
  372. LiApproA[22*i + 15] = CalCtrlPts.at(i).x;
  373. LiApproA[22*i + 16] = CalCtrlPts.at(i).y;
  374. LiApproA[22*i + 17] = CalCtrlPts.at(i).z;
  375. LiApproA[22*i + 18] = 1;
  376. LiApproA[22*i + 19] = PixContner.at(i).y * CalCtrlPts.at(i).x;
  377. LiApproA[22*i + 20] = PixContner.at(i).y * CalCtrlPts.at(i).y;
  378. LiApproA[22*i + 21] = PixContner.at(i).y * CalCtrlPts.at(i).z;
  379. LiApproC[2*i + 0] = -1*PixContner.at(i).x;
  380. LiApproC[2*i + 1] = -1*PixContner.at(i).y;
  381. }
  382. double * LiApproAt = new double[nCalPtsNum*2*11];//A的转置
  383. double * LiApproAtA = new double[11*11];//A的转置 乘以 A
  384. double * LiApproAtC = new double[11];
  385. transpose(LiApproA,LiApproAt,nCalPtsNum*2,11);
  386. mult(LiApproAt,LiApproA,LiApproAtA,11,nCalPtsNum*2,11);
  387. inv(LiApproAtA,11);//LiApproAtA的逆仍为LiApproAtA
  388. mult(LiApproAt,LiApproC,LiApproAtC,11,nCalPtsNum*2,1);
  389. mult(LiApproAtA,LiApproAtC,pPara,11,11,1);
  390. //释放临时内存
  391. delete [] LiApproA;
  392. delete [] LiApproAt;
  393. delete [] LiApproAtA;
  394. delete [] LiApproAtC;
  395. delete [] LiApproC;
  396. CalCtrlPts.clear();
  397. PixContner.clear();
  398. return true; 
  399. }
  400. //返回pElement和pTrueLi,pElems中的顺序依次为x0,y0,fx,ds,dB,Xs,Ys,Zs,t(phi),w,k ; pTrueLi中为L1-L11和k
  401. int CDLTDlg::CalOrtAndLiFactors(vector<PixPoint> xPixContner,vector<GeodeticPoint> CtrlContner,double *li,double *pElems,double *pTrueLi)
  402. {
  403. //搜索像点对应的控制点
  404.     vector<GeodeticPoint> CalCtrlPts;
  405. vector<PixPoint>PixContner;
  406. for (int i =0;i<xPixContner.size();i++)
  407. {
  408. for(int j = 0;j<CtrlContner.size();j++)
  409. {
  410. if (xPixContner.at(i).ID == CtrlContner.at(j).ID)
  411. {
  412. CalCtrlPts.push_back(CtrlContner.at(j));
  413. PixContner.push_back(xPixContner.at(i));
  414. break;
  415. }
  416. }
  417. }
  418. ///////////////////////////////////////////////////////////
  419. int nCalPtsNum = CalCtrlPts.size();
  420. double x0,y0,r2;//r2为像点到像主点的距离平方
  421. BOOL bFlag = true;//迭代标志
  422. double * pL = new double [12];//前11个为li
  423. for (i =0;i<11;i++)
  424.  pL[i] = li[i];
  425. pL[i] = 0.0;
  426.     //分配临时存储空间
  427. double * M = new double[nCalPtsNum*2*12];
  428. double * W = new double[nCalPtsNum * 2];
  429. double * Mt = new double[nCalPtsNum*2*12];//M的转置
  430. double * MtM = new double[12*12];//M的转置 乘以 M
  431. double * MtW = new double[12];
  432. double xoyofenmu,A,B,C,fx,r32;//r3的平方
  433. int nIterationCnt = 0;
  434. while(bFlag)
  435. {
  436. nIterationCnt++;
  437. if (nIterationCnt == 101)
  438. {
  439. //MessageBox("迭代次数达到100次","Error",MB_OK|MB_ICONWARNING);
  440. return -1;
  441. }
  442. xoyofenmu = pL[8]*pL[8] + pL[9]*pL[9] + pL[10]*pL[10];
  443. x0 = -(pL[0]*pL[8] + pL[1]*pL[9] + pL[2]*pL[10])/xoyofenmu;
  444. y0 = -(pL[4]*pL[8] + pL[5]*pL[9] + pL[6]*pL[10])/xoyofenmu;
  445. //逐点计算系数
  446. for (i = 0;i<nCalPtsNum;i++)
  447. {
  448. A = pL[8]*CalCtrlPts.at(i).x + pL[9]*CalCtrlPts.at(i).y + pL[10]*CalCtrlPts.at(i).z + 1;
  449. r2 = pow(PixContner.at(i).x - x0,2) + pow(PixContner.at(i).y - y0,2);
  450.             M[24*i + 0] = -CalCtrlPts.at(i).x/A;
  451. M[24*i + 1] = -CalCtrlPts.at(i).y/A;
  452. M[24*i + 2] = -CalCtrlPts.at(i).z/A;
  453. M[24*i + 3] = -1/A;
  454. M[24*i + 4] = 0;
  455. M[24*i + 5] = 0;
  456. M[24*i + 6] = 0;
  457. M[24*i + 7] = 0;
  458. M[24*i + 8] = -PixContner.at(i).x * CalCtrlPts.at(i).x/A;
  459. M[24*i + 9] = -PixContner.at(i).x * CalCtrlPts.at(i).y/A;
  460. M[24*i + 10] = -PixContner.at(i).x * CalCtrlPts.at(i).z/A;
  461. M[24*i + 11] = -(PixContner.at(i).x - x0)*r2;
  462. M[24*i + 12] = 0;
  463. M[24*i + 13] = 0;
  464. M[24*i + 14] = 0;
  465. M[24*i + 15] = 0;
  466. M[24*i + 16] = -CalCtrlPts.at(i).x/A;
  467. M[24*i + 17] = -CalCtrlPts.at(i).y/A;
  468. M[24*i + 18] = -CalCtrlPts.at(i).z/A;
  469. M[24*i + 19] = -1/A;
  470. M[24*i + 20] = -PixContner.at(i).y * CalCtrlPts.at(i).x/A;
  471. M[24*i + 21] = -PixContner.at(i).y * CalCtrlPts.at(i).y/A;
  472. M[24*i + 22] = -PixContner.at(i).y * CalCtrlPts.at(i).z/A;
  473. M[24*i + 23] = -(PixContner.at(i).y - y0)*r2;
  474. W[2*i + 0] = PixContner.at(i).x/A;
  475.     W[2*i + 1] = PixContner.at(i).y/A;
  476. }
  477. //解求pL
  478.         transpose(M,Mt,nCalPtsNum*2,12);
  479. mult(Mt,M,MtM,12,nCalPtsNum*2,12);
  480. inv(MtM,12);
  481. mult(Mt,W,MtW,12,nCalPtsNum*2,1);
  482.     mult(MtM,MtW,pL,12,12,1);
  483. //求fx--pElems【2】作为迭代结束的标志
  484.         xoyofenmu = pL[8]*pL[8] + pL[9]*pL[9] + pL[10]*pL[10];
  485. x0 = -(pL[0]*pL[8] + pL[1]*pL[9] + pL[2]*pL[10])/xoyofenmu;
  486. y0 = -(pL[4]*pL[8] + pL[5]*pL[9] + pL[6]*pL[10])/xoyofenmu;
  487. r32 = 1/xoyofenmu;
  488. A = r32*(pL[0]*pL[0] + pL[1]*pL[1] + pL[2]*pL[2]) - x0*x0;
  489. B = r32*(pL[4]*pL[4] + pL[5]*pL[5] + pL[6]*pL[6]) - y0*y0;
  490. C = r32*(pL[0]*pL[4] + pL[1]*pL[5] + pL[2]*pL[6]) - x0*y0;
  491. pElems[4] = asin( sqrt( C*C/(A*B) ) );//dB
  492. fx = sqrt(A)*cos(pElems[4]) ;
  493.         if(nIterationCnt == 1)//第一次运算时pElems[2]无值
  494. {
  495. pElems[2] = fx;
  496. continue;
  497. }
  498.         if (fabs(fx - pElems[2])<0.001)
  499.         {
  500. bFlag = false;
  501. break;
  502.         }
  503. pElems[2] = fx;
  504. }
  505. //计算结果
  506. //返回Li系数
  507. for (i=0;i<12;i++)
  508. {
  509. pTrueLi[i] = pL[i];
  510. }
  511. //返回11个内外方位元素参数和变形参数
  512. //x0,y0,fx,ds,dB,Xs,Ys,Zs,t(phi),w,k 
  513.     pElems[0] = x0;//
  514. pElems[1] = y0;//
  515. pElems[2] = fx;//
  516. pElems[3] = sqrt(A/B) -1;//ds
  517. //pElems[4] = ;//dB迭代中已求
  518.    //先求角元素
  519. double a3,b3,c3,b1,b2;
  520. a3 = pL[8]/sqrt(xoyofenmu);
  521. b3 = pL[9]/sqrt(xoyofenmu);
  522. c3 = pL[10]/sqrt(xoyofenmu);
  523. b2 = (pL[5]*sqrt(r32) + b3*y0)*(1+pElems[3])*cos(pElems[4])/fx;
  524. b1 = (pElems[1]*sqrt(r32) + b2*fx*tan(pElems[4]) + b3*x0 )/fx ;
  525. pElems[8] = atan(-a3/c3);//t(phi)
  526. pElems[9] = asin(-b3);//w
  527. pElems[10] = atan(b1/b2);//k
  528.    //再求线元素
  529.     M[0] = pL [0] ;
  530. M[1] = pL [1] ;
  531. M[2] = pL [2] ;
  532. M[3] = pL [4] ;
  533. M[4] = pL [5] ;
  534. M[5] = pL [6] ;
  535. M[6] = pL [8] ;
  536. M[7] = pL [9] ;
  537. M[8] = pL [10] ;
  538. W[0] = -pL [3];
  539. W[1] = -pL [7];
  540. W[2] = -1;
  541. inv(M,3);
  542. mult(M,W,Mt,3,3,1);
  543. pElems[5] = Mt[0];//Xs
  544. pElems[6] = Mt[1];//
  545. pElems[7] = Mt[2];//
  546. //释放临时内存空间
  547. delete [] pL;
  548. delete [] M;
  549. delete [] Mt;
  550. delete [] MtM;
  551. delete [] MtW;
  552. CalCtrlPts.clear();
  553. PixContner.clear();
  554.     return nIterationCnt;
  555. }
  556. void CDLTDlg::CalXYZAndPrecision(vector<PixPoint> LPixContner,vector<PixPoint> RPixContner,double *pLLinar,double *pRLinar,double *pLi1,double *pLi2)
  557. {
  558. //搜索同名像点并进行非线性误差改正
  559.     vector<PRSPoint> CalCtrlPts;
  560. for (int i =0;i<LPixContner.size();i++)
  561. {
  562. for(int j = 0;j<RPixContner.size();j++)
  563. {
  564. if (LPixContner.at(i).ID == RPixContner.at(j).ID)
  565. {
  566. PRSPoint point;
  567. double r21,r22;
  568. //进行线性误差改正
  569. r21 = pow(LPixContner.at(i).x - pLLinar[0],2) + pow(LPixContner.at(i).y - pLLinar[1],2);
  570. r22 = pow(RPixContner.at(j).x - pRLinar[0],2) + pow(RPixContner.at(j).y - pRLinar[1],2);
  571. point.ID = LPixContner.at(i).ID;
  572. point.x1 = LPixContner.at(i).x + pLi1[11]*(LPixContner.at(i).x - pLLinar[0])*r21;
  573. point.y1 = LPixContner.at(i).y + pLi1[11]*(LPixContner.at(i).y - pLLinar[1])*r21;
  574. point.x2 = RPixContner.at(j).x + pLi2[11]*(RPixContner.at(j).x - pRLinar[0])*r22;
  575. point.y2 = RPixContner.at(j).y + pLi2[11]*(RPixContner.at(j).y - pRLinar[1])*r22;
  576. ///计算X,Y,Z的初值
  577. double * A = new double [12];
  578. double * L = new double [4];
  579. double * X = new double [4];
  580. A[0] = pLi1[0] + LPixContner.at(i).x*pLi1[8];
  581. A[1] = pLi1[1] + LPixContner.at(i).x*pLi1[9];
  582. A[2] = pLi1[2] + LPixContner.at(i).x*pLi1[10];
  583. A[3] = pLi1[4] + LPixContner.at(i).y*pLi1[10];
  584. A[4] = pLi1[5] + LPixContner.at(i).y*pLi1[10];
  585. A[5] = pLi1[6] + LPixContner.at(i).y*pLi1[10];
  586. A[6] = pLi2[0] + RPixContner.at(j).x*pLi2[8];
  587. A[7] = pLi2[1] + RPixContner.at(j).x*pLi2[9];
  588. A[8] = pLi2[2] + RPixContner.at(j).x*pLi2[10];
  589. L[0] = -pLi1[3] - LPixContner.at(i).x;
  590. L[1] = -pLi1[7] - LPixContner.at(i).y;
  591. L[2] = -pLi2[3] - RPixContner.at(j).x;
  592. inv(A,3);
  593. mult(A,L,X,3,3,1);
  594. point.X = X[0];
  595. point.Y = X[1];
  596. point.Z = X[2];
  597. CalCtrlPts.push_back(point);
  598. delete [] A;
  599. delete [] L;
  600. delete [] X;
  601. break;
  602. }
  603. }
  604. }
  605. int nCalPtsNum = CalCtrlPts.size();
  606. if(nCalPtsNum < 1) return;
  607. double * N = new double [4 * 3];
  608. double * Nt = new double [4 * 3];
  609. double * NtN = new double [3*3];
  610. double * Q = new double [4];
  611. double * NtQ = new double [3];
  612.     double * SS = new double [3];
  613. double * NSS = new double [4];
  614. double * V = new double [4];
  615. double * Vt = new double [4];
  616. double VtV,A1 ,A2;
  617. //逐点循环迭代求解并输出结果
  618. FILE * fp;
  619. fp = fopen(strResultFileName,"a+");
  620. fprintf(fp,"以下为同名点的大地坐标和精度n 点号       X              Y              Z            精度n");
  621. for (i=0;i<nCalPtsNum;i++)
  622. {
  623. //初始化参数
  624. int bFlag = 3,nCount=0;
  625. double X[3] = {CalCtrlPts.at(i).X, CalCtrlPts.at(i).Y,CalCtrlPts.at(i).Z};//保存计算结果用于比较
  626. while(bFlag)
  627. {
  628. bFlag = 3;
  629. nCount++;
  630. if (nCount == 11)
  631. {
  632. //CalCtrlPts.at(i).ID = -999;  
  633. break;
  634. }
  635. A1 = pLi1[8]*CalCtrlPts.at(i).X + pLi1[9]*CalCtrlPts.at(i).Y + pLi1[10]*CalCtrlPts.at(i).Z + 1;
  636. A2 = pLi2[8]*CalCtrlPts.at(i).X + pLi2[9]*CalCtrlPts.at(i).Y + pLi2[10]*CalCtrlPts.at(i).Z + 1;
  637. N[0] = -(pLi1[0] + pLi1[8]*CalCtrlPts.at(i).x1)/A1; 
  638. N[1] = -(pLi1[1] + pLi1[9]*CalCtrlPts.at(i).x1)/A1;
  639. N[2] = -(pLi1[2] + pLi1[10]*CalCtrlPts.at(i).x1)/A1;
  640. N[3] = -(pLi1[4] + pLi1[8]*CalCtrlPts.at(i).y1)/A1;
  641. N[4] = -(pLi1[5] + pLi1[9]*CalCtrlPts.at(i).y1)/A1;
  642. N[5] = -(pLi1[6] + pLi1[10]*CalCtrlPts.at(i).y1)/A1;
  643. N[6] = -(pLi2[0] + pLi2[8]*CalCtrlPts.at(i).x2)/A2; 
  644. N[7] = -(pLi2[1] + pLi2[9]*CalCtrlPts.at(i).x2)/A2;
  645. N[8] = -(pLi2[2] + pLi2[10]*CalCtrlPts.at(i).x2)/A2;
  646. N[9] = -(pLi2[4] + pLi2[8]*CalCtrlPts.at(i).y2)/A2;
  647. N[10] = -(pLi2[5] + pLi2[9]*CalCtrlPts.at(i).y2)/A2;
  648. N[11] = -(pLi2[6] + pLi2[10]*CalCtrlPts.at(i).y2)/A2;
  649. Q[0] = (pLi1[3] + CalCtrlPts.at(i).x1)/A1;
  650. Q[1] = (pLi1[7] + CalCtrlPts.at(i).y1)/A1;
  651. Q[2] = (pLi2[3] + CalCtrlPts.at(i).x2)/A2;
  652. Q[3] = (pLi2[7] + CalCtrlPts.at(i).y2)/A2;
  653. //计算结果
  654. transpose(N,Nt,4,3);
  655. mult(Nt,N,NtN,3,4,3);
  656. mult(Nt,Q,NtQ,3,4,1);
  657. inv(NtN,3);
  658. mult(NtN,NtQ,SS,3,3,1);
  659. for (int j=0;j<3;j++)
  660. {
  661. if (fabs(SS[j]-X[j])<0.001)
  662. bFlag --;
  663. X[j] = SS[j];//保存上一次计算结果,用比较
  664. }
  665. //保存结果
  666. CalCtrlPts.at(i).X = SS[0];
  667. CalCtrlPts.at(i).Y = SS[1];
  668. CalCtrlPts.at(i).Z = SS[2];
  669. }
  670. //计算中误差
  671. mult(N,SS,NSS,4,3,1);
  672. for (int j=0;j<4;j++)//计算NS + Q
  673. {
  674. V[j] = NSS[j] - Q[j];
  675. }
  676. transpose(V,Vt,4,1);
  677. mult(Vt,V,&VtV,1,4,1);
  678. CalCtrlPts.at(i).m = VtV;
  679. //output 
  680. if (nCount == 11)
  681.     fprintf(fp,"%d     %.6f     %.6f     %.6f    %.6f 迭代次数达10次,计算终止n",
  682. CalCtrlPts.at(i).ID,CalCtrlPts.at(i).X,CalCtrlPts.at(i).Y,CalCtrlPts.at(i).Z,CalCtrlPts.at(i).m);
  683. else
  684. fprintf(fp,"%d     %.6f     %.6f     %.6f   %.6fn",
  685. CalCtrlPts.at(i).ID,CalCtrlPts.at(i).X,CalCtrlPts.at(i).Y,CalCtrlPts.at(i).Z,CalCtrlPts.at(i).m);
  686. }
  687. fclose(fp);
  688. //释放临时内存空间
  689. delete [] N;
  690. delete [] Nt;
  691. delete [] NtN;
  692. delete [] Q;
  693. delete [] NtQ;
  694. delete [] SS;
  695. delete [] NSS;
  696. delete [] V;
  697. delete [] Vt;
  698. CalCtrlPts.clear();
  699. }