误差理论与测量平差课程设计实验报告

时间:2024.3.31

误差理论与测量平差

课程设计报告

l 课程名称:误差理论与测量平差

l 课程题目:   平差计算器       

l 姓名:        江记洲           

l 专业:        测绘工程         

l 学号:        20104166         

l 学院:    土木与水利工程学院   

l 学校:      合肥工业大学       

l 指导老师:    陶庭叶         

一、   实验目的与要求

1)  实验目的:此次的课程设计可以用任何一种计算机语言来编写,这样给我们每个人很多的选择。同时这样也是为了练习同学们对于一门语言的掌握和运用,大大的提高了我们的编程能力。同时,通过对测量数据的误差处理,增强学生对《误差理论与测量平差基础》课程的理解,使学生牢固掌握测量数据处理的基本原理和公式,熟悉测量数据处理的基本技能和计算方法。要求学生综合运用测绘知识、测量平差知识、数学知识和计算机知识,设计数学模型和程序算法,编制程序实现测量数据的自动化处理。

2)  实验要求:要求每位同学独立完成给定测量数据处理的数学模型和算法的设计,编写程序,调测程序,并编写程序设计文档。要求数学模型和算法正确、程序运行正确、设计文档完备。

二、   课程设计主要内容

课程设计的主要内容主要有:

1.  新建一个基于单文档的MFC应用程序。

这只是基本的框架结构,里面包含了几个已知的类,在这些类的基础上,可以增加对象和变量。

然后是增加一个操作矩阵的类 CMatrix 的实现文件,Matrix.cpp和Matrix.h文件是从网上下载的,然后添加工程,创建了一个类,进行矩阵的计算。通过运算符的重载,可以进行加减乘除计算,还可以进行矩阵的转置和求逆等运算。现将该程序的Matrix.cpp文件附录如下:

// Matrix.cpp

#include "StdAfx.h"

#include "Matrix.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

// Construction/Destruction

// 基本构造函数

CMatrix::CMatrix()

{

   m_nNumColumns = 1;

   m_nNumRows = 1;

   m_pData = NULL;

   BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);

   ASSERT(bSuccess);

}

// 指定行列构造函数

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2. int nCols - 指定的矩阵列数

CMatrix::CMatrix(int nRows, int nCols)

{

   m_nNumRows = nRows;

   m_nNumColumns = nCols;

   m_pData = NULL;

   BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);

   ASSERT(bSuccess);

}

// 初始化函数

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2. int nCols - 指定的矩阵列数

//

// 返回值:BOOL 型,初始化是否成功

BOOL CMatrix::Init(int nRows, int nCols)

{

   if (m_pData)

   {

       delete[] m_pData;

       m_pData = NULL;

   }

   m_nNumRows = nRows;

   m_nNumColumns = nCols;

   int nSize = nCols*nRows;

   if (nSize < 0)

       return FALSE;

   // 分配内存

   m_pData = new double[nSize];

  

   if (m_pData == NULL)

       return FALSE;               // 内存分配失败

   if (IsBadReadPtr(m_pData, sizeof(double) * nSize))

       return FALSE;

   // 将各元素值置0

      

   memset(m_pData, 0, sizeof(double) * nSize);

   return TRUE;

}

// 指定值构造函数

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2. int nCols - 指定的矩阵列数

// 3. double value[] - 一维数组,长度为nRows*nCols,存储矩阵各元素的值

CMatrix::CMatrix(int nRows, int nCols, double value[])

{

   m_nNumRows = nRows;

   m_nNumColumns = nCols;

   m_pData = NULL;

   BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);

   ASSERT(bSuccess);

   SetData(value);

}

// 设置矩阵各元素的值

// 参数:

// 1. double value[] - 一维数组,长度为m_nNumColumns*m_nNumRows,存储

//                     矩阵各元素的值

// 返回值:无

void CMatrix::SetData(double value[])

{

   // empty the memory

   memset(m_pData, 0, sizeof(double) * m_nNumColumns*m_nNumRows);

   // copy data

   memcpy(m_pData, value, sizeof(double)*m_nNumColumns*m_nNumRows);

}

// 方阵构造函数

// 参数:

// 1. int nSize - 方阵行列数

CMatrix::CMatrix(int nSize)

{

   m_nNumRows = nSize;

   m_nNumColumns = nSize;

   m_pData = NULL;

   BOOL bSuccess = Init(nSize, nSize);

   ASSERT (bSuccess);

}

// 方阵构造函数

// 参数:

// 1. int nSize - 方阵行列数

// 2. double value[] - 一维数组,长度为nRows*nRows,存储方阵各元素的值

CMatrix::CMatrix(int nSize, double value[])

{

   m_nNumRows = nSize;

   m_nNumColumns = nSize;

   m_pData = NULL;

   BOOL bSuccess = Init(nSize, nSize);

   ASSERT (bSuccess);

   SetData(value);

}

// 拷贝构造函数

// 参数:

// 1. const CMatrix& other - 源矩阵

CMatrix::CMatrix(const CMatrix& other)

{

   m_nNumColumns = other.GetNumColumns();

   m_nNumRows = other.GetNumRows();

   m_pData = NULL;

   BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);

   ASSERT(bSuccess);

   // copy the pointer

   memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);

}

// 析构函数

CMatrix::~CMatrix()

{

   if (m_pData)

   {

       delete[] m_pData;

       m_pData = NULL;

   }

}

// 将方阵初始化为单位矩阵

// 参数:

// 1. int nSize - 方阵行列数

// 返回值:BOOL 型,初始化是否成功

BOOL CMatrix::MakeUnitMatrix(int nSize)

{

   if (! Init(nSize, nSize))

       return FALSE;

   for (int i=0; i<nSize; ++i)

       for (int j=0; j<nSize; ++j)

          if (i == j)

              SetElement(i, j, 1);

   return TRUE;

}

// 将字符串转化为矩阵的值

// 参数:

// 1. CString s - 数字和分隔符构成的字符串

// 2. const CString& sDelim - 数字之间的分隔符,默认为空格

// 3. BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)

//         当该参数为FALSE时,所有元素值都在一行中输入,字符串的第一个

//         数值应为矩阵的行数,第二个数值应为矩阵的列数

// 返回值:BOOL 型,转换是否成功

BOOL CMatrix::FromString(CString s, const CString& sDelim /*= " "*/, BOOL bLineBreak /*= TRUE*/)

{

   if (s.IsEmpty())

       return FALSE;

   // 分行处理

   if (bLineBreak)

   {

       CTokenizer tk(s, "\r\n");

       CStringList ListRow;

       CString sRow;

       while (tk.Next(sRow))

       {

          sRow.TrimLeft();

          sRow.TrimRight();

          if (sRow.IsEmpty())

              break;

          ListRow.AddTail(sRow);

       }

       // 行数

       m_nNumRows = ListRow.GetCount();

       sRow = ListRow.GetHead();

       CTokenizer tkRow(sRow, sDelim);

       CString sElement;

       // 列数

       m_nNumColumns = 0;

       while (tkRow.Next(sElement))

       {

          m_nNumColumns++;

       }

       // 初始化矩阵

       if (! Init(m_nNumRows, m_nNumColumns))

          return FALSE;

       // 设置值

       POSITION pos = ListRow.GetHeadPosition();

       for (int i=0; i<m_nNumRows; i++)

       {

          sRow = ListRow.GetNext(pos);

          int j = 0;

          CTokenizer tkRow(sRow, sDelim);

          while (tkRow.Next(sElement))

          {

              sElement.TrimLeft();

              sElement.TrimRight();

              double v = atof(sElement);

              SetElement(i, j++, v);

          }

       }

       return TRUE;

   }

       // 不分行(单行)处理

   CTokenizer tk(s, sDelim);

   CString sElement;

       // 行数

   tk.Next(sElement);

   sElement.TrimLeft();

   sElement.TrimRight();

   m_nNumRows = atoi(sElement);

   // 列数

   tk.Next(sElement);

   sElement.TrimLeft();

   sElement.TrimRight();

   m_nNumColumns = atoi(sElement);

   // 初始化矩阵

   if (! Init(m_nNumRows, m_nNumColumns))

       return FALSE;

   // 设置值

   int i = 0, j = 0;

   while (tk.Next(sElement))

   {

       sElement.TrimLeft();

       sElement.TrimRight();

       double v = atof(sElement);

       SetElement(i, j++, v);

       if (j == m_nNumColumns)

       {

          j = 0;

          i++;

          if (i == m_nNumRows)

              break;

       }

   }

   return TRUE;

}

// 将矩阵各元素的值转化为字符串

//

// 参数:

// 1. const CString& sDelim - 数字之间的分隔符,默认为空格

// 2 BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)

//

// 返回值:CString 型,转换得到的字符串

CString CMatrix::ToString(const CString& sDelim /*= " "*/, BOOL bLineBreak /*= TRUE*/) const

{

   CString s="";

   for (int i=0; i<m_nNumRows; ++i)

   {

       for (int j=0; j<m_nNumColumns; ++j)

       {

          CString ss;

          ss.Format("%f", GetElement(i, j));

          s += ss;

          if (bLineBreak)

          {

              if (j != m_nNumColumns-1)

                 s += sDelim;

          }

          else

          {

              if (i != m_nNumRows-1 || j != m_nNumColumns-1)

                 s += sDelim;

          }

       }

       if (bLineBreak)

          if (i != m_nNumRows-1)

              s += "\r\n";

   }

   return s;

}

// 将矩阵指定行中各元素的值转化为字符串

// 参数:

// 1. int nRow - 指定的矩阵行,nRow = 0表示第一行

// 2. const CString& sDelim - 数字之间的分隔符,默认为空格

// 返回值:CString 型,转换得到的字符串

CString CMatrix::RowToString(int nRow, const CString& sDelim /*= " "*/) const

{

   CString s = "";

   if (nRow >= m_nNumRows)

       return s;

   for (int j=0; j<m_nNumColumns; ++j)

   {

       CString ss;

       ss.Format("%f", GetElement(nRow, j));

       s += ss;

       if (j != m_nNumColumns-1)

          s += sDelim;

   }

   return s;

}

// 将矩阵指定列中各元素的值转化为字符串

// 参数:

// 1. int nCol - 指定的矩阵行,nCol = 0表示第一列

// 2. const CString& sDelim - 数字之间的分隔符,默认为空格

// 返回值:CString 型,转换得到的字符串

CString CMatrix::ColToString(int nCol, const CString& sDelim /*= " "*/) const

{

   CString s = "";

   if (nCol >= m_nNumColumns)

       return s;

   for (int i=0; i<m_nNumRows; ++i)

   {

       CString ss;

       ss.Format("%f", GetElement(i, nCol));

       s += ss;

       if (i != m_nNumRows-1)

          s += sDelim;

   }

   return s;

}

// 设置指定元素的值

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2. int nCols - 指定的矩阵列数

// 3. double value - 指定元素的值

// 返回值:BOOL 型,说明设置是否成功

BOOL CMatrix::SetElement(int nRow, int nCol, double value)

{

   if (nCol < 0 || nCol >= m_nNumColumns || nRow < 0 || nRow >= m_nNumRows)

       return FALSE;                   // array bounds error

   if (m_pData == NULL)

       return FALSE;                      // bad pointer error

       m_pData[nCol + nRow * m_nNumColumns] = value;

   return TRUE;

}

// 设置指定元素的值

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2. int nCols - 指定的矩阵列数

// 返回值:double 型,指定元素的值

double CMatrix::GetElement(int nRow, int nCol) const

{

   ASSERT(nCol >= 0 && nCol < m_nNumColumns && nRow >= 0 && nRow < m_nNumRows); // array bounds error

   ASSERT(m_pData);                       // bad pointer error

   return m_pData[nCol + nRow * m_nNumColumns] ;

}

// 获取矩阵的列数

// 参数:无

// 返回值:int 型,矩阵的列数

int    CMatrix::GetNumColumns() const

{

   return m_nNumColumns;

}

// 获取矩阵的行数

// 参数:无

// 返回值:int 型,矩阵的行数

int    CMatrix::GetNumRows() const

{

   return m_nNumRows;

}

// 获取矩阵的数据

// 参数:无

// 返回值:double型指针,指向矩阵各元素的数据缓冲区

double* CMatrix::GetData() const

{

   return m_pData;

}

// 获取指定行的向量

// 参数:

// 1. int nRows - 指定的矩阵行数

// 2.  double* pVector - 指向向量中各元素的缓冲区

// 返回值:int 型,向量中元素的个数,即矩阵的列数

int CMatrix::GetRowVector(int nRow, double* pVector) const

{

   if (pVector == NULL)

       delete pVector;

   pVector = new double[m_nNumColumns];

   ASSERT(pVector != NULL);

   for (int j=0; j<m_nNumColumns; ++j)

       pVector[j] = GetElement(nRow, j);

   return m_nNumColumns;

}

// 获取指定列的向量

// 参数:

// 1. int nCols - 指定的矩阵列数

// 2.  double* pVector - 指向向量中各元素的缓冲区

// 返回值:int 型,向量中元素的个数,即矩阵的行数

int CMatrix::GetColVector(int nCol, double* pVector) const

{

   if (pVector == NULL)

       delete pVector;

   pVector = new double[m_nNumRows];

   ASSERT(pVector != NULL);

   for (int i=0; i<m_nNumRows; ++i)

       pVector[i] = GetElement(i, nCol);

   return m_nNumRows;

}

// 重载运算符=,给矩阵赋值

// 参数:

// 1. const CMatrix& other - 用于给矩阵赋值的源矩阵

// 返回值:CMatrix型的引用,所引用的矩阵与other相等

CMatrix& CMatrix::operator=(const CMatrix& other)

{

   if (&other != this)

   {

       BOOL bSuccess = Init(other.GetNumRows(), other.GetNumColumns());

       ASSERT(bSuccess);

       // copy the pointer

       memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);

   }

   // finally return a reference to ourselves

   return *this ;

}

// 重载运算符==,判断矩阵是否相等

// 参数:

// 1. const CMatrix& other - 用于比较的矩阵

// 返回值:BOOL 型,两个矩阵相等则为TRUE,否则为FALSE

BOOL CMatrix::operator==(const CMatrix& other) const

{

   // 首先检查行列数是否相等

   if (m_nNumColumns != other.GetNumColumns() || m_nNumRows != other.GetNumRows())

       return FALSE;

   for (int i=0; i<m_nNumRows; ++i)

   {

       for (int j=0; j<m_nNumColumns; ++j)

       {

          if (GetElement(i, j) != other.GetElement(i, j))

              return FALSE;

       }

   }

   return TRUE;

}

// 重载运算符!=,判断矩阵是否不相等

// 参数:

// 1. const CMatrix& other - 用于比较的矩阵

// 返回值:BOOL 型,两个不矩阵相等则为TRUE,否则为FALSE

BOOL CMatrix::operator!=(const CMatrix& other) const

{

   return !(*this == other);

}

// 重载运算符+,实现矩阵的加法

// 参数:

// 1. const CMatrix& other - 与指定矩阵相加的矩阵

// 返回值:CMatrix型,指定矩阵与other相加之和

CMatrix   CMatrix::operator+(const CMatrix& other) const

{

   // 首先检查行列数是否相等

   ASSERT (m_nNumColumns == other.GetNumColumns() && m_nNumRows == other.GetNumRows());

   // 构造结果矩阵

   CMatrix    result(*this) ;      // 拷贝构造

   // 矩阵加法

   for (int i = 0 ; i < m_nNumRows ; ++i)

   {

       for (int j = 0 ; j <  m_nNumColumns; ++j)

           result.SetElement(i, j, result.GetElement(i, j) + other.GetElement(i, j)) ;

   }

   return result ;

}

// 重载运算符-,实现矩阵的减法

// 参数:

// 1. const CMatrix& other - 与指定矩阵相减的矩阵

// 返回值:CMatrix型,指定矩阵与other相减之差

CMatrix   CMatrix::operator-(const CMatrix& other) const

{

   // 首先检查行列数是否相等

   ASSERT (m_nNumColumns == other.GetNumColumns() && m_nNumRows == other.GetNumRows());

   // 构造目标矩阵

   CMatrix    result(*this) ;      // copy ourselves

   // 进行减法操作

   for (int i = 0 ; i < m_nNumRows ; ++i)

   {

       for (int j = 0 ; j <  m_nNumColumns; ++j)

          result.SetElement(i, j, result.GetElement(i, j) - other.GetElement(i, j)) ;

   }

   return result ;

}

// 重载运算符*,实现矩阵的数乘

// 参数:

// 1. double value - 与指定矩阵相乘的实数

// 返回值:CMatrix型,指定矩阵与value相乘之积

CMatrix   CMatrix::operator*(double value) const

{

   // 构造目标矩阵

   CMatrix    result(*this) ;      // copy ourselves

   // 进行数乘

   for (int i = 0 ; i < m_nNumRows ; ++i)

   {

       for (int j = 0 ; j <  m_nNumColumns; ++j)

          result.SetElement(i, j, result.GetElement(i, j) * value) ;

   }

   return result ;

}

// 重载运算符*,实现矩阵的乘法

// 参数:

// 1. const CMatrix& other - 与指定矩阵相乘的矩阵

// 返回值:CMatrix型,指定矩阵与other相乘之积

CMatrix   CMatrix::operator*(const CMatrix& other) const

{

   // 首先检查行列数是否符合要求

   ASSERT (m_nNumColumns == other.GetNumRows());

   // construct the object we are going to return

   CMatrix    result(m_nNumRows, other.GetNumColumns()) ;

   // 矩阵乘法,即

   // [A][B][C]   [G][H]     [A*G + B*I + C*K][A*H + B*J + C*L]

   // [D][E][F] * [I][J] =   [D*G + E*I + F*K][D*H + E*J + F*L]

   //             [K][L]

       double value ;

   for (int i = 0 ; i < result.GetNumRows() ; ++i)

   {

       for (int j = 0 ; j < other.GetNumColumns() ; ++j)

       {

          value = 0.0 ;

          for (int k = 0 ; k < m_nNumColumns ; ++k)

          {

              value += GetElement(i, k) * other.GetElement(k, j) ;

          }

          result.SetElement(i, j, value) ;

       }

   }

   return result ;

}

// 矩阵的转置

// 参数:无

// 返回值:CMatrix型,指定矩阵转置矩阵

CMatrix CMatrix::Transpose() const

{

   // 构造目标矩阵

   CMatrix    Trans(m_nNumColumns, m_nNumRows);

   // 转置各元素

   for (int i = 0 ; i < m_nNumRows ; ++i)

   {

       for (int j = 0 ; j < m_nNumColumns ; ++j)

          Trans.SetElement(j, i, GetElement(i, j)) ;

   }

   return Trans;

}

// 实矩阵求逆的全选主元高斯-约当法

// 参数:无

// 返回值:BOOL型,求逆是否成功

BOOL CMatrix::InvertGaussJordan()

{

   int *pnRow, *pnCol,i,j,k,l,u,v;

    double d = 0, p = 0;

   // 分配内存

    pnRow = new int[m_nNumColumns];

    pnCol = new int[m_nNumColumns];

   if (pnRow == NULL || pnCol == NULL)

       return FALSE;

   // 消元

    for (k=0; k<=m_nNumColumns-1; k++)

    {

       d=0.0;

        for (i=k; i<=m_nNumColumns-1; i++)

       {

          for (j=k; j<=m_nNumColumns-1; j++)

          {

              l=i*m_nNumColumns+j; p=fabs(m_pData[l]);

              if (p>d)

              {

                 d=p;

                 pnRow[k]=i;

                 pnCol[k]=j;

              }

          }

       }

              // 失败

       if (d == 0.0)

       {

          delete[] pnRow;

          delete[] pnCol;

          return FALSE;

       }

        if (pnRow[k] != k)

       {

          for (j=0; j<=m_nNumColumns-1; j++)

          {

              u=k*m_nNumColumns+j;

              v=pnRow[k]*m_nNumColumns+j;

              p=m_pData[u];

              m_pData[u]=m_pData[v];

              m_pData[v]=p;

          }

       }

       if (pnCol[k] != k)

       {

          for (i=0; i<=m_nNumColumns-1; i++)

            {

              u=i*m_nNumColumns+k;

              v=i*m_nNumColumns+pnCol[k];

              p=m_pData[u];

              m_pData[u]=m_pData[v];

              m_pData[v]=p;

            }

       }

        l=k*m_nNumColumns+k;

        m_pData[l]=1.0/m_pData[l];

        for (j=0; j<=m_nNumColumns-1; j++)

       {

          if (j != k)

            {

              u=k*m_nNumColumns+j;

              m_pData[u]=m_pData[u]*m_pData[l];

          }

       }

        for (i=0; i<=m_nNumColumns-1; i++)

       {

          if (i!=k)

          {

              for (j=0; j<=m_nNumColumns-1; j++)

              {

                 if (j!=k)

                 {

                     u=i*m_nNumColumns+j;

                     m_pData[u]=m_pData[u]-m_pData[i*m_nNumColumns+k]*m_pData[k*m_nNumColumns+j];

                 }

                }

          }

       }

        for (i=0; i<=m_nNumColumns-1; i++)

       {

          if (i!=k)

            {

              u=i*m_nNumColumns+k;

              m_pData[u]=-m_pData[u]*m_pData[l];

          }

       }

    }

    // 调整恢复行列次序

    for (k=m_nNumColumns-1; k>=0; k--)

    {

       if (pnCol[k]!=k)

       {

          for (j=0; j<=m_nNumColumns-1; j++)

            {

              u=k*m_nNumColumns+j;

              v=pnCol[k]*m_nNumColumns+j;

              p=m_pData[u];

              m_pData[u]=m_pData[v];

              m_pData[v]=p;

            }

       }

        if (pnRow[k]!=k)

       {

          for (i=0; i<=m_nNumColumns-1; i++)

            {

              u=i*m_nNumColumns+k;

              v=i*m_nNumColumns+pnRow[k];

              p=m_pData[u];

              m_pData[u]=m_pData[v];

              m_pData[v]=p;

            }

       }

    }

   // 清理内存

   delete[] pnRow;

   delete[] pnCol;

   // 成功返回

   return TRUE;

}

// 对称正定矩阵的求逆

//

// 参数:无

//

// 返回值:BOOL型,求逆是否成功

BOOL CMatrix::InvertSsgj()

{

   int i, j ,k, m;

    double w, g, *pTmp;

   // 临时内存

    pTmp = new double[m_nNumColumns];

   // 逐列处理

    for (k=0; k<=m_nNumColumns-1; k++)

    {

       w=m_pData[0];

        if (w == 0.0)

        {

          delete[] pTmp;

          return FALSE;

       }

        m=m_nNumColumns-k-1;

        for (i=1; i<=m_nNumColumns-1; i++)

        {

          g=m_pData[i*m_nNumColumns];

          pTmp[i]=g/w;

            if (i<=m)

              pTmp[i]=-pTmp[i];

            for (j=1; j<=i; j++)

              m_pData[(i-1)*m_nNumColumns+j-1]=m_pData[i*m_nNumColumns+j]+g*pTmp[j];

        }

      m_pData[m_nNumColumns*m_nNumColumns-1]=1.0/w;

        for (i=1; i<=m_nNumColumns-1; i++)

          m_pData[(m_nNumColumns-1)*m_nNumColumns+i-1]=pTmp[i];

    }

   // 行列调整

    for (i=0; i<=m_nNumColumns-2; i++)

       for (j=i+1; j<=m_nNumColumns-1; j++)

          m_pData[i*m_nNumColumns+j]=m_pData[j*m_nNumColumns+i];

   // 临时内存清理

   delete[] pTmp;

   return TRUE;

}

2.  创建五个新的对话框。

创建对话框相对来说比较简单,只需在菜单栏中点击New Dialog就可以创建,每个对话框都有自己的ID号。笔者课程设计中共创建了五个对话框,每个对话框都创建了一个类相对应。如图给出条件平差和历史记录的对话框的截图:

3.  在每个对话框里面添加需要的控件。

在每个不同平差类型的对话框中添加能够实现不同功能的函数,响应函数的不同决定了不同的执行结果。

4.  给每个需要实现不同功能的函数添加消息响应函数。

条件平差的计算和保存响应函数:

void CTjpc1::OnButton1()

{

// TODO: Add your control notification handler code here

UpdateData();

// 在这里义了这几个矩阵

CMatrix jza,jza1,jzw,jzq,jzv,jzv1,jzn,jzk,jza0;

double a0,r;

//  将输入的已知矩阵各元素由字符转化为数值

jza.FromString(m_1edit1);

jzw.FromString(m_1edit2);

jzq.FromString(m_1edit3);

    r=1.0/(jza.GetNumRows());

jza1=jza.Transpose();

jzn=jza*jzq*jza1;

//   求jzn的逆矩阵

if(jzn.InvertGaussJordan())

        m_1edit4=jzn.ToString(" ");

else

        m_1edit4="失败";

jzn.FromString(m_1edit4);

jzk=jzn*jzw*(-1);

//   求出由各个数值的改正数组成的jzv

jzv=jzq*jza1*jzk;

m_1edit4=jzv.ToString(" ");

    jzv1=jzv.Transpose();

//  求协因数阵的逆矩阵权阵,此处用jzq代替一下

if(jzq.InvertGaussJordan())

        m_1edit5=jzq.ToString(" ");

else

        m_1edit5="失败";

jzq.FromString(m_1edit5);

jza0=jzv1*jzq*jzv;

jza0=jza0*r;

m_1edit5=jza0.ToString(" ");

a0=atof(m_1edit5);

a0=sqrt(a0); 

m_1edit5.Format("%f",a0);

//  将所求得的输入到第四个框和第五个框里

GetDlgItem(IDC_EDIT4)->SetWindowText(m_1edit4);

GetDlgItem(IDC_EDIT5)->SetWindowText(m_1edit5);

CFile file;

    file.Open("1.txt", CFile::modeCreate | CFile::modeNoTruncate |CFile::modeWrite);

file.SeekToEnd();

CString a="\r\n";

file.Write(a,strlen(a));

file.Write("条件平差的记录数据:", strlen("条件平差的记录数据:"));

file.Write(a,strlen(a));

file.Write("A矩阵为:", strlen("A矩阵为:"));

file.Write(a,strlen(a));

    file.Write(m_1edit1, strlen(m_1edit1));

file.Write(a,strlen(a));

file.Write("W矩阵为:", strlen("A矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_1edit2, strlen(m_1edit2));

file.Write(a,strlen(a));

file.Write("Q矩阵为:", strlen("Q矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_1edit3, strlen(m_1edit3));

file.Write(a,strlen(a));

file.Write("V矩阵为:", strlen("V矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_1edit4, strlen(m_1edit4));

file.Write(a,strlen(a));

file.Write("单位中误差为:", strlen("单位中误差为:"));

    file.Write(a,strlen(a));

file.Write(m_1edit5, strlen(m_1edit5));

    file.Write(a,strlen(a));

    file.Close();

UpdateData(FALSE);

}

清零的函数:

void CTjpc1::OnButton2()

{

// TODO: Add your control notification handler code here

GetDlgItem(IDC_EDIT1)->SetWindowText(NULL);

GetDlgItem(IDC_EDIT2)->SetWindowText(NULL);

GetDlgItem(IDC_EDIT3)->SetWindowText(NULL);

GetDlgItem(IDC_EDIT4)->SetWindowText(NULL);

GetDlgItem(IDC_EDIT5)->SetWindowText(NULL);

}

间接平差的计算和保存响应函数:

void CJjpc2::OnButton3()

{

// TODO: Add your control notification handler code here

UpdateData();

CMatrix jzb,jzb1,jzp,jzw,jzl,jzv,jzv1,jzx,jzn,jza0;

double a0,r;int i;

jzb.FromString(m_2edit1);

jzp.FromString(m_2edit2);

jzl.FromString(m_2edit3);

if((jzb.GetNumRows==jzp.GetNumRows)&(jzp.GetNumRows==jzl.GetNumRows))

{

i=(jzb.GetNumRows()-jzb.GetNumColumns());

r=1.0/i;

jzb1=jzb.Transpose();

jzn=jzb1*jzp*jzb;//m_2edit4=jzn.ToString(" ");

jzw=jzb1*jzp*jzl;

if(jzn.InvertGaussJordan())

        m_2edit4=jzn.ToString(" ");

else

        MessageBox("数据输入有错,请仔细查出错误,并重新输入。");

       

jzn.FromString(m_2edit4);

jzx=jzn*jzw;

jzv=(jzb*jzx-jzl);

jzv1=jzv.Transpose();

jza0=jzv1*jzp*jzv*r;

m_2edit5=jza0.ToString(" ");

a0=atof(m_2edit5);

a0=sqrt(a0); 

m_2edit5.Format("%f",a0);

m_2edit4=jzv.ToString(" ");

GetDlgItem(IDC_EDIT4)->SetWindowText(m_2edit4);

GetDlgItem(IDC_EDIT5)->SetWindowText(m_2edit5);

}

else

{

    MessageBox("矩阵输入的有错误!请重新输入!");

}

CFile file;

    file.Open("2.txt", CFile::modeCreate | CFile::modeNoTruncate |CFile::modeWrite);

file.SeekToEnd();

CString a="\r\n";

file.Write(a,strlen(a));

file.Write("间接平差的记录数据:", strlen("间接平差的记录数据:"));

file.Write(a,strlen(a));

file.Write("B矩阵为:", strlen("B矩阵为:"));

file.Write(a,strlen(a));

    file.Write(m_2edit1, strlen(m_2edit1));

file.Write(a,strlen(a));

file.Write("P矩阵为:", strlen("P矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_2edit2, strlen(m_2edit2));

file.Write(a,strlen(a));

file.Write("L矩阵为:", strlen("L矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_2edit3, strlen(m_2edit3));

file.Write(a,strlen(a));

file.Write("V矩阵为:", strlen("V矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_2edit4, strlen(m_2edit4));

file.Write(a,strlen(a));

file.Write("单位中误差为:", strlen("单位中误差为:"));

    file.Write(a,strlen(a));

file.Write(m_2edit5, strlen(m_2edit5));

    file.Write(a,strlen(a));

    file.Close();

UpdateData(FALSE);

}

附有参数条件平差的计算和保存响应函数:

void CFctjpc3::OnButton5()

{

// TODO: Add your control notification handler code here

UpdateData();

// 在这里义了这几个矩阵

CMatrix jza,jza1,jzb,jzb1,jzw,jzq,jzv,jzv1,jzn1,jzn2,jzx,jzk,jza0;

double a0,r;

//  将输入的已知矩阵各元素由字符转化为数值

jza.FromString(m_3edit1);

jzb.FromString(m_3edit2);

jzw.FromString(m_3edit3);

jzq.FromString(m_3edit4);

    r=1.0/(jzb.GetNumRows()-jzb.GetNumColumns());

jza1=jza.Transpose();

jzb1=jzb.Transpose();

jzn1=jza*jzq*jza1;

//   求jzn的逆矩阵

if(jzn1.InvertGaussJordan())

        m_3edit5=jzn1.ToString(" ");

else

        MessageBox("数据输入有错,请仔细查出错误,并重新输入。");

jzn1.FromString(m_3edit5);

jzn2=jzb1*jzn1*jzb;

{

    if(jzn2.InvertGaussJordan())

        m_3edit6=jzn2.ToString(" ");

    else

        MessageBox("数据输入有错,请仔细查出错误,并重新输入。");

}

jzn2.FromString(m_3edit6);

jzx=jzn2*jzb1*jzn1*jzw*(-1);

jzk=jzn1*(jzb*jzx+jzw)*(-1);

//   求出由各个数值的改正数组成的jzv

jzv=jzq*jza1*jzk;

m_3edit5=jzv.ToString(" ");

    jzv1=jzv.Transpose();

//  求协因数阵的逆矩阵权阵,此处用jzq代替一下

{

    if(jzq.InvertGaussJordan())

    m_3edit6=jzq.ToString(" ");

    else

        m_3edit6="失败";

}

jzq.FromString(m_3edit6);

jza0=jzv1*jzq*jzv;

jza0=jza0*r;

m_3edit6=jza0.ToString(" ");

a0=atof(m_3edit6);

a0=sqrt(a0); 

m_3edit6.Format("%f",a0);

//  将所求得的输入到第四个框和第五个框里

GetDlgItem(IDC_EDIT5)->SetWindowText(m_3edit5);

GetDlgItem(IDC_EDIT6)->SetWindowText(m_3edit6);

CFile file;

    file.Open("3.txt", CFile::modeCreate | CFile::modeNoTruncate |CFile::modeWrite);

file.SeekToEnd();

CString a="\r\n";

file.Write(a,strlen(a));

file.Write("附有参数的条件平差的记录数据:", strlen("附有参数的条件平差的记录数据:"));

file.Write(a,strlen(a));

file.Write("B矩阵为:", strlen("B矩阵为:"));

file.Write(a,strlen(a));

    file.Write(m_3edit1, strlen(m_3edit1));

file.Write(a,strlen(a));

file.Write("P矩阵为:", strlen("P矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_3edit2, strlen(m_3edit2));

file.Write(a,strlen(a));

file.Write("W矩阵为:", strlen("W矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_3edit3, strlen(m_3edit3));

file.Write(a,strlen(a));

file.Write("Q矩阵为:", strlen("Q矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_3edit4, strlen(m_3edit4));

file.Write(a,strlen(a));

file.Write("V矩阵为:", strlen("V矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_3edit5, strlen(m_3edit5));

file.Write(a,strlen(a));

file.Write("单位中误差为:", strlen("单位中误差为:"));

    file.Write(a,strlen(a));

file.Write(m_3edit6, strlen(m_3edit6));

    file.Write(a,strlen(a));

    file.Close();

UpdateData(FALSE);

}

附有限制性条件间接平差的计算和保存响应函数:

void CFxjjpc::OnButton7()

{

// TODO: Add your control notification handler code here

UpdateData();

CMatrix jzb,jzb1,jzc,jzc1,jzp,jzw,jzwx,jzl,jzv,jzv1,jzx,jzn1,jzn2,jzks,jza0;

double a0,r;

jzb.FromString(m_4edit1);

jzc.FromString(m_4edit2);

jzp.FromString(m_4edit3);

jzl.FromString(m_4edit4);

jzwx.FromString(m_4edit5);

r=1.0/(jzb.GetNumRows()-jzb.GetNumColumns()+jzc.GetNumRows());

jzb1=jzb.Transpose();

jzn1=jzb1*jzp*jzb;

jzw=jzb1*jzp*jzl;

    jzc1=jzc.Transpose();

if(jzn1.InvertGaussJordan())

        m_4edit6=jzn1.ToString(" ");

else

        MessageBox("数据输入有错,请仔细查出错误,并重新输入。");

       

jzn1.FromString(m_4edit6);

jzn2=jzc*jzn1*jzc1;

if(jzn2.InvertGaussJordan())

        m_4edit7=jzn2.ToString(" ");

else

        MessageBox("数据输入有错,请仔细查出错误,并重新输入。");

       

jzn2.FromString(m_4edit7);

//jzks=jzn2*(jzc*jzn1*jzw+jzwx);

jzx=(jzn1-jzn1*jzc1*jzn2*jzc*jzn1)*jzw-jzn1*jzc1*jzn2*jzwx;

jzv=jzb*jzx-jzl;

jzv1=jzv.Transpose();

jza0=jzv1*jzp*jzv*r;

m_4edit7=jza0.ToString(" ");

a0=atof(m_4edit7);

a0=sqrt(a0); 

m_4edit7.Format("%f",a0);

m_4edit6=jzv.ToString(" ");

GetDlgItem(IDC_EDIT6)->SetWindowText(m_4edit6);

GetDlgItem(IDC_EDIT7)->SetWindowText(m_4edit7);

CFile file;

    file.Open("4.txt", CFile::modeCreate | CFile::modeNoTruncate |CFile::modeWrite);

file.SeekToEnd();

CString a="\r\n";

file.Write(a,strlen(a));

file.Write("附有限制条件的间接平差的记录数据:", strlen("附有限制条件的间接平差的记录数据:"));

file.Write(a,strlen(a));

file.Write("B矩阵为:", strlen("B矩阵为:"));

file.Write(a,strlen(a));

    file.Write(m_4edit1, strlen(m_4edit1));

file.Write(a,strlen(a));

file.Write("C矩阵为:", strlen("C矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_4edit2, strlen(m_4edit2));

file.Write(a,strlen(a));

file.Write("P矩阵为:", strlen("P矩阵为:"));  

    file.Write(a,strlen(a));

file.Write(m_4edit3, strlen(m_4edit3));

file.Write(a,strlen(a));

file.Write("L矩阵为:", strlen("L矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_4edit4, strlen(m_4edit4));

file.Write(a,strlen(a));

file.Write("Wx矩阵为:", strlen("Wx矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_4edit5, strlen(m_4edit5));

file.Write(a,strlen(a));

file.Write("V矩阵为:", strlen("V矩阵为:"));

    file.Write(a,strlen(a));

file.Write(m_4edit6, strlen(m_4edit6));

file.Write(a,strlen(a));

file.Write("单位中误差为:", strlen("单位中误差为:"));

    file.Write(a,strlen(a));

file.Write(m_4edit7, strlen(m_4edit7));

    file.Write(a,strlen(a));

    file.Close();

UpdateData(FALSE);

}

在读取历史记录的对话框中,消息响应函数是:

先看看查看历史记录对话框的分布(如下图)

各个控件的消息响应函数大同小异

void CLsjl::OnButton1()

{

// TODO: Add your control notification handler code here

CString str;

CFile f;

f.Open("1.txt",CFile::modeReadWrite);

f.Read(str.GetBuffer(f.GetLength()),f.GetLength());

f.Close();

GetDlgItem( IDC_EDIT1 )->SetWindowText(str);

}

查看不同平差类型计算历史记录控件的响应函数中的代码只是f.Open("文件名",CFile::modeReadWrite);的文件名不同而已。

5.  给主界面和其它的对话框添加图片等美化工作。

未进行处理的界面是灰色的,单调乏味,需要添加图片等进行美化。但是由于时间较短,做的不是太好。

6.  输入书本例子中的已知值,得出运算结果。比对正确的结果,查出并改正程序中的错误。

程序编完后,笔者进行了详细的验算,程序中已经保留了验证的数据和结果。

三、   实验感想

  误差理论与测量平差的课程设计这件事,老师很早就和我们说了。是为了给我们充足的时间准备,然后做到最好。我们牢固掌握测量数据处理的基本原理和公式,熟练掌握测量数据处理的基本技能和计算方法。

    在将近一个月的时间里,通过自己的学习,从无到有。简单的学习了C++的编程知识,主要是运用MFC,基本上实现了四种平差模型的计算。其中也遇到了很多的问题,开始最棘手的问题是如何读取对话框中编辑框中的矩阵并进行相关的计算。在这个问题上耽搁了几天。后来经过上网搜索,知道可以用一个类,在网上下了并且添加到工程。通过运算符的重载,计算上变的很简单。

    后来遇到的一个问题就是在保存计算数据的时候,输入到文本中时,如何进行换行?这个在CSDN论坛上有类似的帖子,看过后如醍醐灌顶,就是定义一个字符“\r\n”,通过输入这个字符,可以实现换行。

    虽然大家都说C++难,但是一个一个问题的去解决,问题都会迎刃而解。

通过这个课程设计,自己简单地掌握了C++,以后自己会更加深入地去学习,力求做到更好。

四、   参考文献

孙鑫视频[孙鑫]

《面向对象程序设计与VC程序设计入门》[主编余祖龙, 孙开琼]

更多相关推荐:
测量平差课程设计实习报告

河南城建学院测绘与城市空间信息系课程设计报告学生学号061410203学生班级0614102学生姓名豆婷婷专业测绘工程指导教师梁玉保时间20xx1224至20xx122820xx年12月28日设计名称误差理论与...

测量平差课程设计实习报告

湖南科技大学建筑与城市规划学院测量平差课程设计实习报告专业班级姓名学号指导老师20xx年1月9日一课程设计的性质目的和任务测量平差课程设计是完成测量平差基础课程教学后进行的综合应用该课程基本知识和技能的一个教学...

21306116郭皛_测量平差课程设计报告

测量平差课程设计水准网间接平差附有参数条件平差方法与间接平差比较姓名郭皛学号21306116指导教师喻国荣东南大学测绘工程系20xx年1月1日1摘要在这次课程设计中主要完成了应用测量平差软件包平差各种高程控制网...

误差理论与测量平差课程设计报告

误差理论与测量平差课程设计报告课题水准网严密平差及精度评定院校山东交通学院系别土木工程系指导教师赵斌臣等班级测绘071姓名李大志目录一目录1二序言2三设计思路3四程序流程图4五程序及说明5六计算结果12七总结1...

测量平差课程设计报告

东南大学交通学院测量平差课程设计报告设计题目专业班级学号姓名指导老师日期019测绘工程专业1课程设计目的2课程设计任务目录2223课程设计重点以及基本要求4课程设计具体要求5课程设计案例及分析6课程设计展示成果...

误差理论与测量平差基础课程设计报告

误差理论与测量平差基础课程设计导线网平差计算间接平差法计算待定点坐标平差值任务及精度要求某工程按城市测量规范CJJ899布设一二级导线网作为平面控制网主要技术要求为平均边长200m测角中误差8导线全长相对闭合差...

测量平差课程设计

课程名称学院姓名年课程设计误差理论与测量平差基础矿业学院专业yyzzhh学号111111111120xx年01月06日课程设计任务书一设计目的及意义测量平差是一门理论与实践并重的课程测量平差课程设计是测量数据处...

测量平差课程设计

课程设计南昌工程学院水利与生态工程学院课程设计报告设计名称误差理论与测量平差课程设计学院水利与生态工程学院专业测绘工程组别第一小组组长xx指导教师xx老师时间20xx1224至20xx122820xx年12月2...

测量平差课程设计指导书

误差理论与测量平差课程设计指导书测绘工程专业20xx年6月误差理论与测量平差课程设计指导书适用专业测绘工程学分数1学时数1周1设计的目的测量平差是一门理论与实践并重的课程测量平差课程设计是测量数据处理理论学习的...

测量平差基础课程设计

1测量平差基础课程设计题目导线平差班级测绘二班姓名李文义学号080615380完成日期2测量平差课程设计测量平差简介测量平差的主要任务是对一系列带有观测误差的观测值运用概率统计的方法来消除它们之间的不符值求出未...

测量平差课程设计

一设计目的误差理论与测量平差基础是一门理论与实践并重的课程测量平差课程设计是测量数据处理理论学习的一个重要实践环节是在学生学习了专业基础理论课误差理论与测量平差基础课程后进行的一门实践课程其目的是增强学生对测量...

测量平差课程设计

一课程设计的目的目的课程设计是误差理论与测量平差教学的组成部分除验证课堂理论外也是巩固和深化课堂所学知识有机结合的重要环节更是培养学生动手能力和训练严格的实践科学态度和工作作风的手段通过课程设计增强平差相关理论...

测量平差课程设计报告(24篇)