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

📄 backwardsection_xiayudlg.cpp

📁 本程序为近景摄影测量的单像空间后方交会算法,采用VC++实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	while(nDiedaiNum<600 )//最多迭代600次
	{
	
	    //计算旋转矩阵
        rotation(pdfElement[FAI],pdfElement[OMIGA],pdfElement[KAMA],pdfR);

		CString strNum ;
		strNum.Format("第%d次迭代:",nDiedaiNum+1);
		file.WriteString(strNum);
		file.WriteString("\n");
		//输出旋转矩阵到文件
		file.WriteString("旋转矩阵R:");

		file.WriteString("\n");

		for( i=0;i<9;i++)
		{
			if( (i!=0) && ((i%3)==0) )
				file.WriteString("\n");

			CString strTemp;
			strTemp.Format("%lf",pdfR[i]);
			strTemp+= " ";
			file.WriteString(strTemp);

		}

		file.WriteString("\n");
		file.WriteString("\n");
		file.WriteString("\n");

 		double *pdfMeanX = new double[nCtrlPointNum];
		double *pdfMeanY = new double[nCtrlPointNum];
		double *pdfMeanZ = new double[nCtrlPointNum];

		//逐点计算像点坐标近似值
		for(int j=0;j<nCtrlPointNum;j++)
		{
			pdfMeanX[j] = pdfR[0]*((pGcp+j)->ptGroundCoor.dfX-pdfElement[X])
				+pdfR[3]*((pGcp+j)->ptGroundCoor.dfY-pdfElement[Y])
				+pdfR[6]*((pGcp+j)->ptGroundCoor.dfZ-pdfElement[Z]);

			pdfMeanY[j] = pdfR[1]*((pGcp+j)->ptGroundCoor.dfX-pdfElement[X])
				+pdfR[4]*((pGcp+j)->ptGroundCoor.dfY-pdfElement[Y])
				+pdfR[7]*((pGcp+j)->ptGroundCoor.dfZ-pdfElement[Z]);

			pdfMeanZ[j] = pdfR[2]*((pGcp+j)->ptGroundCoor.dfX-pdfElement[X])
				+pdfR[5]*((pGcp+j)->ptGroundCoor.dfY-pdfElement[Y])
				+pdfR[8]*((pGcp+j)->ptGroundCoor.dfZ-pdfElement[Z]);

            double dfx = dfx0 - dffk*pdfMeanX[j]/pdfMeanZ[j];//像点坐标x近似值

            double dfy = dfy0 - dffk*pdfMeanY[j]/pdfMeanZ[j];//像点坐标y近似值

			//误差方程式子系数项
			*(pdfa+j*12+0) = (pdfR[0]*dffk+pdfR[2]*(dfx-dfx0))/pdfMeanZ[j];

			*(pdfa+j*12+1) = (pdfR[3]*dffk+pdfR[5]*(dfx-dfx0))/pdfMeanZ[j];

 			*(pdfa+j*12+2) = (pdfR[6]*dffk+pdfR[8]*(dfx-dfx0))/pdfMeanZ[j];

			*(pdfa+j*12+3) = (dfy-dfy0)*sin(pdfElement[OMIGA])-
				((dfx-dfx0)/dffk*((dfx-dfx0)*cos(pdfElement[KAMA])-(dfy-dfy0)*sin(pdfElement[KAMA]))+
				dffk*cos(pdfElement[KAMA]))*cos(pdfElement[OMIGA]);

			*(pdfa+j*12+4) = -1*dffk*sin(pdfElement[KAMA])-(dfx-dfx0)/dffk*((dfx-dfx0)*sin(pdfElement[KAMA])+(dfy-dfy0)*cos(pdfElement[KAMA]));
		
			*(pdfa+j*12+5) = dfy-dfy0;

			*(pdfa+j*12+6) = (pdfR[1]*dffk+pdfR[2]*(dfy-dfy0))/pdfMeanZ[j];

			*(pdfa+j*12+7) = (pdfR[4]*dffk+pdfR[5]*(dfy-dfy0))/pdfMeanZ[j];

			*(pdfa+j*12+8) = (pdfR[7]*dffk+pdfR[8]*(dfy-dfy0))/pdfMeanZ[j];

			*(pdfa+j*12+9) = -1*(dfx-dfx0)*sin(pdfElement[OMIGA])-
				((dfy-dfy0)/dffk*((dfx-dfx0)*cos(pdfElement[KAMA])-(dfy-dfy0)*sin(pdfElement[KAMA]))-
				dffk*sin(pdfElement[KAMA]))*cos(pdfElement[OMIGA]);

 			*(pdfa+j*12+10) = -1*dffk*cos(pdfElement[KAMA])-(dfy-dfy0)/dffk*((dfx-dfx0)*sin(pdfElement[KAMA])+(dfy-dfy0)*cos(pdfElement[KAMA]));

			*(pdfa+j*12+11) = -1*(dfx-dfx0);

    		//误差方程式子常数项
			*(pdfL+j*2+0) = (pGcp+j)->ptImgCoor.dfX - dfx; //控制点影像坐标x - 影像坐标x的近似值

            *(pdfL+j*2+1) = (pGcp+j)->ptImgCoor.dfY - dfy; //控制点影像坐标y - 影像坐标y的近似值
   
		}

         
		//...输出中间过程,供调试用...
		file.WriteString("误差方程式系数矩阵A:");
		file.WriteString("\n");
		for(int i=0;i<2*nCtrlPointNum*6;i++)
		{
		
			if( (i!=0) && ((i%6)==0) )
				file.WriteString("\n");
			CString strTemp;
			strTemp.Format("%lf",pdfa[i]);
			strTemp+= " ";
			file.WriteString(strTemp);


		}

		file.WriteString("\n");
		file.WriteString("\n");
		file.WriteString("\n");

		file.WriteString("误差方程式常数项矩阵L:");
		file.WriteString("\n");
		for( i=0;i<2*nCtrlPointNum;i++)
		{
		
			if( (i!=0) && ((i%1)==0) )
				file.WriteString("\n");
			CString strTemp;
			strTemp.Format("%lf",pdfL[i]);
			strTemp+= " ";
			file.WriteString(strTemp);


		}

		file.WriteString("\n");
		file.WriteString("\n");
		file.WriteString("\n");

		//求系数矩阵的转置
        transpose(pdfa, pdfaT, 2*nCtrlPointNum, 6);

		//求系数矩阵A的转置与A的乘积
		mult(pdfaT,pdfa, pdfaMutaT, 6, 2*nCtrlPointNum, 6);
        
 		//求系数矩阵A的转置与A的乘积的逆
        BOOL b = invers_matrix(pdfaMutaT,6); 

  		//求系数矩阵A的转置与A的乘积的逆 与 A的转置的乘积
		mult(pdfaMutaT,pdfaT,pdfBridge,6, 6,2*nCtrlPointNum);

   		//求系数矩阵A的转置与A的乘积的逆 与 A的转置的乘积 与常数项的乘积 得到最后的改正数
		mult(pdfBridge,pdfL,Result,6, 2*nCtrlPointNum,1);

		//输出每次迭代外方位元素改正数
  		file.WriteString("外方位元素改正数:");

		file.WriteString("\n");

		for( i=0;i<6;i++)
		{
			if( (i!=0) && ((i%1)==0) )
				file.WriteString("\n");
			CString strTemp;
			strTemp.Format("%.15f",Result[i]);
				strTemp+= " ";
			file.WriteString(strTemp);

		}
		file.WriteString("\n");
		file.WriteString("\n");
		file.WriteString("\n");

		//迭代记数器
		nDiedaiNum++;
		       
		//用未知数近似值与上次迭代计算的改正数之和作为新的近似值
		pdfElement[X] += Result[0];

		pdfElement[Y] += Result[1];

		pdfElement[Z] += Result[2];

		pdfElement[FAI] += Result[3];

		pdfElement[OMIGA] += Result[4];

		pdfElement[KAMA] += Result[5];

		//限差小于阈值时,迭代结束,求得解
  		file.WriteString("外方位元素值:");
		file.WriteString("\n");
		for( i=0;i<6;i++)
		{
			if( (i!=0) && ((i%1)==0) )
				file.WriteString("\n");
			CString strTemp;
			strTemp.Format("%.15f",pdfElement[i]);
				strTemp+= " ";
		file.WriteString(strTemp);

		}
		file.WriteString("\n");
		file.WriteString("\n");
		file.WriteString("\n");

		//迭代结束条件,
        if( (fabs(Result[3]*180/PI*60*60)<0.1) && (fabs(Result[4]*180/PI*60*60)<0.1) 
			&& (fabs(Result[5]*180/PI*60*60)<0.1) &&( fabs(Result[0]*180/PI*60*60)>0.06 ) )//注意fabs(Result[0]*180/PI*60*60)>0.06控制仅靠外方位线元素约束出现的非正常解,这个问题很有意思...夏宇,04.10.
		{
			CString strTip;
			strTip = "解算过程及结果已经输出到文件";
			strTip += m_strPathName;
			strTip += "中";
			AfxMessageBox(strTip);
			bRight = TRUE;
			break;
		}

	}
	if(bRight == FALSE)
	{
			CString strTip;
			strTip = "没有符合条件的解!    解算过程已经输出到文件";
			strTip += m_strPathName;
			strTip += "中";
			AfxMessageBox(strTip);

	}

	file.Close();
    
	CDialog::OnOK();
}

//计算旋转矩阵
void CBackWardSection_XiaYuDlg::rotation(double fai,double omiga,double kappa,double *R)
{
	R[0]=  cos(fai)*cos(kappa)-sin(fai)*sin(omiga)*sin(kappa);
	R[1]= -cos(fai)*sin(kappa)-sin(fai)*sin(omiga)*cos(kappa);
	R[2]= -sin(fai)*cos(omiga);
	R[3]=  cos(omiga)*sin(kappa);
	R[4]=  cos(omiga)*cos(kappa);
	R[5]= -sin(omiga);
	R[6]=  sin(fai)*cos(kappa)+cos(fai)*sin(omiga)*sin(kappa);
	R[7]= -sin(fai)*sin(kappa)+cos(fai)*sin(omiga)*cos(kappa);
	R[8]=  cos(fai)*cos(omiga);
}

//矩阵求逆
BOOL CBackWardSection_XiaYuDlg:: invers_matrix(double *m1,int n)
{
	int *is,*js;
	int i,j,k,l,u,v;
	double temp,max_v;
	is=(int *)malloc(n*sizeof(int));
	js=(int *)malloc(n*sizeof(int));
	if(is==NULL||js==NULL)
	{
		printf("out of memory!\n");
		return(0);
	}
	for(k=0;k<n;k++)
	{
		max_v=0.0;
		for(i=k;i<n;i++)
			for(j=k;j<n;j++)
			{
				temp=fabs(m1[i*n+j]);
				if(temp>max_v)
				{
					max_v=temp; is[k]=i; js[k]=j;
				}
			}
			if(max_v==0.0)
			{
				free(is); free(js);
				printf("invers is not availble!\n");
				return(0);
			}
			if(is[k]!=k)
				for(j=0;j<n;j++)
				{
					u=k*n+j; v=is[k]*n+j;
					temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;
				}
				if(js[k]!=k)
					for(i=0;i<n;i++)
					{
						u=i*n+k; v=i*n+js[k];
						temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;
					}
					l=k*n+k;
					m1[l]=1.0/m1[l];
					for(j=0;j<n;j++)
						if(j!=k)
						{
							u=k*n+j;
							m1[u]*=m1[l];
						}
						for(i=0;i<n;i++)
							if(i!=k)
								for(j=0;j<n;j++)
									if(j!=k)
									{
										u=i*n+j;
										m1[u]-=m1[i*n+k]*m1[k*n+j];
									}
									for(i=0;i<n;i++)
										if(i!=k)
										{
											u=i*n+k;
											m1[u]*=-m1[l];
										}
	}
	for(k=n-1;k>=0;k--)
	{
		if(js[k]!=k)
			for(j=0;j<n;j++)
			{
				u=k*n+j; v=js[k]*n+j;
				temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;
			}
			if(is[k]!=k)
				for(i=0;i<n;i++)
				{
					u=i*n+k; v=i*n+is[k];
					temp=m1[u]; m1[u]=m1[v]; m1[v]=temp;
				}
	}
	free(is); free(js);
	return(1);
}
//矩阵转置
void CBackWardSection_XiaYuDlg::transpose(double *m1, double *m2, int m, int n)
{
  int i,j;
  for(i=0;i<m;i++)
     for(j=0;j<n;j++)
		m2[j*m+i]=m1[i*n+j];
  return;
}

//矩阵相乘
void CBackWardSection_XiaYuDlg::mult(double *m1, double *m2, double *result, int i_1, int j_12, int j_2)
{
	int i,j,k;
	for(i=0;i<i_1;i++)
		for(j=0;j<j_2;j++)
		{
			result[i*j_2+j]=0.0;
			for(k=0;k<j_12;k++)
				result[i*j_2+j]+=m1[i*j_12+k]*m2[j+k*j_2];
		 }
	  return ;
}


void CBackWardSection_XiaYuDlg::OnClickListgcp(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	CEditDlg dlg;
	
	//	dlg.m_dfX = ;
	
	int nItem = 0;
	POSITION pos = m_ListGcp.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		if(MessageBox("添加控制点?","后方交会",MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
		{
			int nNum = m_ListGcp.GetItemCount();
			
			m_ListGcp.InsertItem(nNum,"");//插入控制点记录
		  
			CString strText;
			strText.Format("%d",nNum+1);
		    m_ListGcp.SetItem(nNum,0,LVIF_TEXT,strText,0,LVIF_STATE,0,0); //设置控制点编号

			int nItemTemp = nNum-1;
			CString strValue;
			strValue = m_ListGcp.GetItemText(nItemTemp,1);
			double m_dfX = atof(strValue);
			strValue = m_ListGcp.GetItemText(nItemTemp,2);
			double m_dfY = atof(strValue);
			strValue = m_ListGcp.GetItemText(nItemTemp,3);
			double m_dfZ = atof(strValue);
			strValue = m_ListGcp.GetItemText(nItemTemp,4);
			double m_dfImgx = atof(strValue);
			strValue = m_ListGcp.GetItemText(nItemTemp,5);
			double m_dfImgy = atof(strValue);
			
			CString strConversion;
			strConversion.Format("%lf",m_dfX);
			m_ListGcp.SetItemText(nNum,1,strConversion);
			
			strConversion.Format("%lf",m_dfY);
			m_ListGcp.SetItemText(nNum,2,strConversion);
			
			strConversion.Format("%lf",m_dfZ);
			m_ListGcp.SetItemText(nNum,3,strConversion);
			
			strConversion.Format("%lf",m_dfImgx);
			m_ListGcp.SetItemText(nNum,4,strConversion);
			
			strConversion.Format("%lf",m_dfImgy);
			m_ListGcp.SetItemText(nNum,5,strConversion);
		}
		return;
	}
	else
	{
	   while (pos)
	   {
		  nItem = m_ListGcp.GetNextSelectedItem(pos);
		 
	   }
	}
	CString strText;
	strText.Format("%d",nItem+1);
	dlg.m_strVary = strText;

	CString strValue;
	strValue = m_ListGcp.GetItemText(nItem,1);
	dlg.m_dfX = atof(strValue);
	strValue = m_ListGcp.GetItemText(nItem,2);
	dlg.m_dfY = atof(strValue);
	strValue = m_ListGcp.GetItemText(nItem,3);
	dlg.m_dfZ = atof(strValue);
	strValue = m_ListGcp.GetItemText(nItem,4);
	dlg.m_dfImgx = atof(strValue);
	strValue = m_ListGcp.GetItemText(nItem,5);
	dlg.m_dfImgy = atof(strValue);

 // GetDlgItem(IDC_STATICVARY)->SetWindowText(strText);
    
	if(dlg.DoModal()==IDOK)
	{
		CString strConversion;
		strConversion.Format("%lf",dlg.m_dfX);
		m_ListGcp.SetItemText(nItem,1,strConversion);

		strConversion.Format("%lf",dlg.m_dfY);
		m_ListGcp.SetItemText(nItem,2,strConversion);

		strConversion.Format("%lf",dlg.m_dfZ);
		m_ListGcp.SetItemText(nItem,3,strConversion);

		strConversion.Format("%lf",dlg.m_dfImgx);
		m_ListGcp.SetItemText(nItem,4,strConversion);

		strConversion.Format("%lf",dlg.m_dfImgy);
		m_ListGcp.SetItemText(nItem,5,strConversion);
	}
	*pResult = 0;
}

void CBackWardSection_XiaYuDlg::OnBeginlabeleditListgcp(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	// TODO: Add your control notification handler code here
	
	*pResult = 0;
}

//函数名:OnAction
//参数:无
//功能:输出结果文件
void CBackWardSection_XiaYuDlg::OnAction() 
{
	CFileDialog dlg(FALSE,"txt",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"TXT Files (*.txt)|*.txt||",NULL );
	if(dlg.DoModal()==IDOK)
	{
	   m_strPathName = dlg.GetPathName();
	}
	UpdateData(FALSE);
  
}

⌨️ 快捷键说明

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