《测绘程序开发实习》导线网平差 C++上机实验报告 CSU

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU

  • 一、 实现功能(VS2017制作)
  • 二、 主要模块
  • 三、 系统设计
    • 3.1主要类结构
    • 3.2类功能说明:
    • 3.3对Do类的着重说明
      • 3.3.1整体框架介绍
        • 3.3.3.1系数B矩阵的赋值、常数项F矩阵的赋值
          • 3.3.3.1.1系数B矩阵
          • 3.3.3.1.2 F矩阵的赋值
          • 3.3.3.1.3 BF 赋值函数
        • 3.3.3.2 P矩阵的赋值
    • 4.1初始界面
    • 4.2运行截图
    • 4.3输出至txt中
    • 4.4输出至excel中
    • 4.5鲁棒性展示
    • 4.6画图
    • 4.7帮助
    • 4.8示例数据
  • 五、代码展示及控件ID
    • 5.1 文件 < Data_P.cpp >
    • 5.2文件< Data_Obslength .h>
    • 5.3 文件 < Data_Obslength .cpp >
    • 5.4 文件< Data_Obsangle.h >
    • 5.5文件< Data_Obsangle.cpp >
    • 5.6 文件 < Data_P.h >
    • 5.7 文件 < Data_P.cpp >
    • 5.8 文件 < Do.h >
    • 5.9文件 < Do.cpp>
    • 5.10 文件 < CTraversenetwork10zrxDlg.cpp>部分代码
    • 5.11 文件 < DrawEx .h>
    • 5.12 文件 < DrawEx .cpp>
  • 六、计划与总结
  • 6.1 时间计划安排
  • 6.2 感想及总结
      • 7月1日
      • 7月2日
      • 7月3日
      • 7月4日
      • 7月5日
      • 7月6日
      • 7月7日
      • 7月8日
      • 7月9日
      • 7月10日
      • 7月11日
      • 代码虽多 不要贪杯~

一、 实现功能(VS2017制作)

导线网平差的程序。

二、 主要模块

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第1张图片

三、 系统设计

3.1主要类结构

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第2张图片

3.2类功能说明:

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第3张图片

3.3对Do类的着重说明

3.3.1整体框架介绍

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第4张图片
3.3.2概算部分:
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第5张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第6张图片
Tab、A的计算为:
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第7张图片

Tab’=Tab+A, 为前进方向的左角 Tab可由a,b两点的坐标反算而得
A’=t_ak-t_ab,t_ak,t_ab为方向观测值
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第8张图片
3.3.3 平差部分:
平差计算原理:
设:观测值为L,其权为P,相应的改正数为V,必要观测数为t。
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第9张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第10张图片

3.3.3.1系数B矩阵的赋值、常数项F矩阵的赋值
3.3.3.1.1系数B矩阵

如图B矩阵可分为4部分:左上角、右上角、左下角、右下角部分。
B矩阵对应的行是:方向角度观测数+边长观测数
对应的列是:未知点个数*2(本题平面维度x,y)+基础测站数。
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第11张图片
1)关于基础测站数,即右上角数据的说明:以样例数据一为说明(样例数据在后文有完整版)
由于降低了难度,并没有采取史赖伯一次约化,而采取了最小二乘算法。
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第12张图片
2)关于方向角度观测数的系数,即左上角数据的说明
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第13张图片

3)关于边长观测数的系数,即左下角数据的说明
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第14张图片

3.3.3.1.2 F矩阵的赋值

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第15张图片

3.3.3.1.3 BF 赋值函数

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第16张图片

3.3.3.2 P矩阵的赋值

根据先验方向观测中误差和边长观测中误差来定权
1)方向观测值的权
在等精度方向观测的控制网中,可把方向观测值的权定为1,不同精度的观测网中,则选择其中一种作为单位权中误差u(单位:秒),其它方向观测值中误差为m(单位:秒),则p=μ2/m2
2)边长观测值的权
p_s=μ2/(m_s2 ),其中边长中误差可由m_s=±(A+B⋅S⋅0.1)或m_s=±√S B (单位:厘米)计算,A为测距仪常数误差,B为测距仪比例误差因子,S为边长的长度(单位:公里)。在导线网中一般取方向观测值中误差为单位权中误差。例:观测方向中误差 .边长测量中误差 ,可假设单位权中误差则方向观测权 ,则方向观测值的权为1,观测边权为=100/Si。
以上定权的方式还不是严密的,因为角度和边长是不同的观测量,可采用赫尔默特方差份量估计,迭代定权。
四、界面展示及实例数据

4.1初始界面

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第17张图片

4.2运行截图

以样例数据一为例为例
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第18张图片

4.3输出至txt中

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第19张图片

4.4输出至excel中

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第20张图片

4.5鲁棒性展示

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第21张图片

4.6画图

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第22张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第23张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第24张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第25张图片

4.7帮助

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第26张图片

4.8示例数据

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第27张图片

五、代码展示及控件ID

5.1 文件 < Data_P.cpp >

#include "stdafx.h"
#include "Data_P.h"
Data_P::Data_P()
{
}
Data_P::~Data_P()
{
}

5.2文件< Data_Obslength .h>

#pragma once
#include"Data_P.h"
class Data_Obslength
{
public:
	Data_Obslength();
	~Data_Obslength();
	Data_P *pFront_id;//观测前站
	Data_P *pBack_id;//观测后站
	double dFB_dist;//观测距离
};

5.3 文件 < Data_Obslength .cpp >

#include "stdafx.h"
#include "Data_Obslength.h"
Data_Obslength::Data_Obslength()
{
	pFront_id = NULL;
	pBack_id = NULL;
	dFB_dist = 0;
}
Data_Obslength::~Data_Obslength()
{
}

5.4 文件< Data_Obsangle.h >

#pragma once
//储存角类信息
#include "Angle.h"
#include "Data_Obslength.h"
class Data_Obsangle
{
public:
	Data_Obsangle();
	~Data_Obsangle();
	Data_P *pStation;//测站
	Data_P *pEnd;//照准
	Angle ObsAngel;//观测角度
};

5.5文件< Data_Obsangle.cpp >

#include "stdafx.h"
#include "Data_Obsangle.h"


Data_Obsangle::Data_Obsangle()
{
}


Data_Obsangle::~Data_Obsangle()
{
}

5.6 文件 < Data_P.h >

#pragma once
class Data_P
{
public:
	Data_P();
	~Data_P();
	CString strID;
	double dx;
	double dy;
	int flag;
	
	//下列元素仅未知点有
	double dmx;
	double dmy;
	double dmk;
	double dQ;//长半径方位角
	double dE;//长半径
	double dF;//短半径
};

5.7 文件 < Data_P.cpp >

#include "stdafx.h"
#include "Data_P.h"
Data_P::Data_P()
{
}
Data_P::~Data_P()
{
}

5.8 文件 < Do.h >

//进行导线网水准网操作类
//2019/07/02
#pragma once
#include  
#include //引用eigen类
//#include"Data_P.h"//引用已知控制点类
//#include "Data_Obslength.h"//引用观测边类
#include "Data_Obsangle.h"//引用观测角类
using namespace Eigen; //引用eigen类 操作步骤:属性 包含文件的路径
using namespace std;
class Do
{
//私有数据成员
private:
	Data_P *cp;//定义已知点指针
	Data_P *up;//定义未知点指针
	Data_Obslength *Dist_obs;//定义观测边指针
	Data_Obsangle *Angle_obs;//定义观测角
	int iSum_cp;//定义已知点总个数
	int iSum_up;//定义未知点总个数
	int iAngle_Station;//定义测站数 需修改鲁棒性
	int iSum_Dist_obs;//定义观测值总边长个数
	int iSum_Angle_obs;//定义观测角总个数
	double alfa_wrong;//定义角度误差 鲁棒性
	double length_wrong;//定义边长误差 鲁棒性
//平差成员
	MatrixXd B;//矩阵B
	MatrixXd F;//矩阵f
	MatrixXd P;//矩阵P
	MatrixXd v;//矩阵v
	MatrixXd Nbb;//矩阵Nbb
	MatrixXd Qxx;//矩阵Qxx
	double r0;//单位权中误差
//供输出用
	CString Result;
	CString EstrOut;//Excel模式
//私有成员函数
private:
	int Div(const CString strLine, char split, CStringArray &strArray);//字符串分割函数
	void LinetoCString(CString Result, CString &strOut, CString &EstrOut);//输出一行数据
	void MatrixtoCstring(MatrixXd A, CString &Result, CString &strOut, CString &EstrOut);//输出矩阵至CString中
	Data_P *Search_cp(CString strID);//搜索已知点返回对应站储存的地址
	Data_P *Search_up(CString strID);//返回已知点对应站储存的地址
	Data_P *Search_allp(CString strID);//返回所有点对应站储存的地址
	double Process_Rad(double dx1, double dy1, double dx2, double dy2);//由(dx1,dy1)、(dx2,dy2)求方位角 返回弧度
	//平差
	void BF_angle_abcd(Data_Obsangle Angle_obs, double &a, double &b, double &_a, double &_b);//计算角度
	void BF_angle_f(Data_Obsangle Angle_ob, double &f);//计算角度值对应的f
	void BF_dist_abcdf(Data_Obslength Dist_ob, double &a, double &b, double &_a, double &_b,double &f);//计算边长观测值对应的f
	void Adjustment_BF();//计算B、F系数阵
	void Adjustment_P();//计算P矩阵
	void Adjustment_accuracy();//经度评定
	//画图排序模块
	double Min1_max2_x(Data_P *cp, int iSum_cp, int tag);//求x最小值最大值
	double Min1_max2_y(Data_P *cp, int iSum_cp, int tag);//求x最小值最大值
    //画图
	void Draw_tri(CDC* pDC, double x, double y, double length,double a);//画三角形
	void Draw_ro(double &x, double &y, double alfa, CRect &rect, double dx, double dy,double ro1, double ro2);//坐标旋转转换
public:
	Do();
	~Do();
	int estimate();//数据概算
	void adjustment_main();//平差主函数
	bool read();//读取函数
	void out();//输出计算函数
	void ReportExcel();//输出至excel
	void Reporttxt();//输出至txt
	//void main();//主函数进行综合操作
	void draw(CDC* pDC, CRect rect,double coefficient,double alfa,double dx,double dy, double ro1, double ro2);//画图
	CString strOut;//txt 
};

5.9文件 < Do.cpp>

#include "stdafx.h"
#include "Do.h"
#define PI 3.14159265358979323846

Do::Do()
{
	cp = NULL;
	this->iSum_cp = 0;
	this->iSum_up = 0;
	strOut = (_T(""));
	EstrOut = (_T(""));
}


//***********************************
//析构函数 删除指针
//***********************************
Do::~Do()
{/*
	delete [] cp;
	delete[] up;
	delete[] Dist_obs;
	delete[] Angle_obs;*/
}

//***********************************
//字符分割函数
//***********************************
int Do::Div(const CString strLine, char split, CStringArray &strArray)
{
	strArray.RemoveAll();//自带清空属性
	CString temp = strLine;
	int tag = 0;
	while (1)
	{
		tag = temp.Find(split);
		if (tag >= 0)
		{
			strArray.Add(temp.Left(tag));
			temp = temp.Right(temp.GetLength() - tag - 1);
		}
		else { break; }
	}
	strArray.Add(temp);
	return strArray.GetSize();
}


//***********************************
//输出一行数据,并赋值给strOut、EstrOut
//***********************************
void Do::LinetoCString(CString Result, CString &strOut, CString &EstrOut)//输出一行数据
{
	CString temp;
	temp.Format(Result);
	strOut += temp;
	strOut += "\r\n";
	EstrOut += temp;
	EstrOut += "\n";
}

//***********************************
//输出矩阵,并赋值给strOut、EstrOut
//***********************************
void Do::MatrixtoCstring(MatrixXd A, CString &Result, CString &strOut,CString &EstrOut)
{
	Result.Format(_T("%s%d%s%d\r\n"), _T("----------(支持matlab矩阵)矩阵大小(行列):"), A.rows(), _T("X"), A.cols());
	strOut += Result;
	Result.Format(_T("%s\t%d%s%d\n"), _T("(支持matlab矩阵)矩阵大小(行列):"), A.rows(), _T("X"), A.cols());
	EstrOut += Result;
	for (int i = 0; i < A.rows(); i++)
	{
		for (int j = 0; j < A.cols(); j++)
		{
			Result.Format(_T("  %.6f"), A(i, j));
			strOut += Result;
		}
		if (i != A.rows() - 1)
		{
			strOut += ";\r\n";
		}
		else
		{
			strOut += "\r\n";
		}

	}
	for (int i = 0; i < A.rows(); i++)
	{
		for (int j = 0; j < A.cols(); j++)
		{
			Result.Format(_T(" %.6f\t"), A(i, j));
			EstrOut += Result;
		}
		if (i != A.rows() - 1)
		{
			EstrOut += ";\n";
		}
		else
		{
			EstrOut += "\n";
		}

	}
}

//***********************************
//ID已知点点位搜索
//***********************************
Data_P *Do::Search_cp(CString strID)
{
	for (int i = 0; i < iSum_cp; i++)
	{
		if (strID == cp[i].strID)
		{
			return &cp[i];
		}
	}
	return NULL;
}


//***********************************
//ID未知点点位搜索
//***********************************
Data_P *Do::Search_up(CString strID)
{
	for (int i = 0; i < iSum_up; i++)
	{
		if (strID == up[i].strID)
		{
			return &up[i];
		}
	}
	return NULL;
}


//***********************************
//所有点点位搜索
//***********************************
Data_P *Do::Search_allp(CString strID)
{
	Data_P *temp_p;
	temp_p = Search_cp(strID);
	if (temp_p == NULL)
	{
		temp_p = Search_up(strID);
	}
	return temp_p;
}


//***********************************
//由(dx1,dy1)、(dx2,dy2)求方位角 返回弧度
//***********************************
double Do::Process_Rad(double dx1, double dy1, double dx2, double dy2)
{
	double dx = dx2 - dx1;
	double dy = dy2 - dy1;
	double dRad;
	if (dy > 0) {
		if (dx < 0) {
			dRad = atan(dy / dx) + PI;//第二象限
		}
		else if (dx > 0) {
			dRad = atan(dy / dx);//第一象限
		}
		else {
			dRad = PI / 2;//位于Y轴正方向
		}
	}
	else if (dy < 0) {
		if (dx < 0) {
			dRad = atan(dy / dx) + PI;//第三象限
		}
		else if (dx > 0) {
			dRad = atan(dy / dx) + 2 * PI;//第四象限
		}
		else {
			dRad = PI * 3 / 2;//位于Y轴负方向
		}
	}
	else {
		if (dx > 0) {
			dRad = 0;//位于X正半轴
		}
		else if (dx < 0) {
			dRad = PI;//位于X负半轴
		}
		else {
			AfxMessageBox(_T("您不能输入相同的坐标。"));//(x1,y1)==(x2,y2)的情况  
			return 0;
		}
	}
	return dRad;
}


//***********************************
//读取函数
//***********************************
bool Do::read()
{
	CFileDialog dlgFile(TRUE, _T("txt"), NULL,
		OFN_ALLOWMULTISELECT | OFN_EXPLORER,
		//_T("(文本文件)|*.txt"));
		_T(""));
	if (dlgFile.DoModal() == IDCANCEL) return 0;
	CString strName = dlgFile.GetPathName();//获取打开文件文件名(路径)
	setlocale(LC_ALL, "");
	CStdioFile sf;
	if (!sf.Open(strName, CFile::modeRead)) return 0;//打开strName文件路径中的内容
	CString strLine;
	CString strContent;//接受内容字符串
	CStringArray array;//供下文分割使用
	strContent.Empty();//strContent中内容清空
	//开始读数据 
	BOOL bEOF = sf.ReadString(strLine);//第一行
	if (bEOF == 0) { AfxMessageBox(_T("空数据")); return 0; }
	if (strLine!=_T("[ControlPoint]")) { AfxMessageBox(_T("数据错误")); return 0; }
	//读取控制点
	bEOF = sf.ReadString(strLine);//第二行 
	if (bEOF == 0) { AfxMessageBox(_T("数据不规范")); return 0; }
	iSum_cp= _ttoi(strLine);//读取控制点个数
	cp = new Data_P[iSum_cp];
	int i = 0;
	while (iflag == 1 && Angle_obs[i].pEnd->flag == 1)//如果观测的前后站都是找到了
				{
					//寻找符合某个基站算出位置的  找准站没位置的 
					//计算其方位角后,交给下个for循坏
					for (int j = 0; j < iSum_Angle_obs; j++)
					{
						if (Angle_obs[j].pStation->strID == Angle_obs[i].pStation->strID&&Angle_obs[j].pEnd->flag == -1)
						{
							Angle ji_alfa = Angle_obs[j].ObsAngel - Angle_obs[i].ObsAngel;
							Angle i_alfa = Angle(Process_Rad(Angle_obs[i].pStation->dx, Angle_obs[i].pStation->dy, Angle_obs[i].pEnd->dx, Angle_obs[i].pEnd->dy), RAD);
							double azi = ji_alfa(RAD) + i_alfa(RAD);//计算方位角
							double dDist;
							//寻找相应的边长观测是否存在 按方向和观测值来求坐标
							for (int k = 0; k < iSum_Dist_obs; k++)//按边长观测值计算三边网中待定点的近似坐标 
							{
								if (
									(Dist_obs[k].pFront_id->strID == Angle_obs[j].pStation->strID
										&&Dist_obs[k].pBack_id->strID == Angle_obs[j].pEnd->strID) ||
										(Dist_obs[k].pFront_id->strID == Angle_obs[j].pEnd->strID
											&&Dist_obs[k].pBack_id->strID == Angle_obs[j].pStation->strID)
									)//寻找边长是否存在
								{
									dDist = Dist_obs[k].dFB_dist;

									Angle_obs[j].pEnd->dx = Angle_obs[j].pStation->dx + dDist * cos(azi);
									Angle_obs[j].pEnd->dy = Angle_obs[j].pStation->dy + dDist * sin(azi);
									Angle_obs[j].pEnd->flag = 1;//做标记为已确定的观测值  
									icount++;
								}
							}
							
						}
					}
				}
			}

		} while (icount < iSum_up);
			is = 1;
	}
	//输出概算数据
	LinetoCString(_T("----------------------------坐标概算----------------------------"), strOut, EstrOut);
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\r\n"), up[i].strID, up[i].dx, up[i].dy);
		strOut += Result;
	}
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\n"), up[i].strID, up[i].dx, up[i].dy);
		EstrOut += Result;
	}
	return 0;
}


//***********************************
B矩阵前面的角度赋值
//***********************************
void Do::BF_angle_abcd(Data_Obsangle Angle_obs, double &a, double &b, double &_a, double &_b)
{
	double dx0 = Angle_obs.pEnd->dx- Angle_obs.pStation->dx ;
	double dy0 = Angle_obs.pEnd->dy- Angle_obs.pStation->dy;
	double S0 = sqrt(dx0*dx0 + dy0 * dy0);
	double temp_a = (180 * 3600 / PI)*dy0 / (S0*S0* 1000.0);
	double temp_b = -(180 * 3600 / PI)*dx0 / (S0*S0 * 1000.0);
	a = temp_a;
	_a = -temp_a;
	b = temp_b;
	_b =- temp_b;
}

//***********************************
f赋值
//***********************************
void Do::BF_angle_f(Data_Obsangle Angle_ob,double &f)//计算角度值对应的f
{
	Angle zero_1;//例如 1 3站 40度 ,1 2站  0度。求1,2站的方位角
	for (int i = 0; i < iSum_Angle_obs; i++)
	{
		if (Angle_ob.pStation->strID == Angle_obs[i].pStation->strID
			&& (Angle_obs[i].ObsAngel(DEG)< 1e-6))
		{
			zero_1 = Angle(Process_Rad(Angle_obs[i].pStation->dx, Angle_obs[i].pStation->dy, Angle_obs[i].pEnd->dx, Angle_obs[i].pEnd->dy),RAD);
			break;
		}
	}
	Angle zero_2= Angle(Process_Rad(Angle_ob.pStation->dx, Angle_ob.pStation->dy, Angle_ob.pEnd->dx, Angle_ob.pEnd->dy),RAD);//利用1,3站坐标推算其方位角
	Angle zero_3 = Angle((zero_2(RAD) - zero_1(RAD)),RAD);//两方位角相减
	zero_3 = Angle(((zero_3(DMS) < 0) ? (2 * PI + zero_3(RAD)) : zero_3(RAD)),RAD);//若小于零+2*pi
	Angle temp_obs = Angle(Angle_ob.ObsAngel(RAD),RAD);//观测值
	double temp_obs_DMS = temp_obs(RAD);
	f = temp_obs(RAD) - zero_3(RAD);
	f = f * 180 * 3600 / PI;//换算成秒
}

//***********************************
//B矩阵距离赋值
//***********************************
void Do::BF_dist_abcdf(Data_Obslength Dist_ob, double &a, double &b, double &_a, double &_b, double &f)//计算边长观测值对应的f
{
	double temp_a, temp_b, dX0, dY0, dS0;
	dX0 = Dist_ob.pBack_id->dx - Dist_ob.pFront_id->dx;
	dY0 = Dist_ob.pBack_id->dy - Dist_ob.pFront_id->dy;
	dS0 = sqrt(dX0*dX0 + dY0 * dY0);//观测边长距离
	temp_a = dX0 / dS0;
	temp_b = dY0 / dS0;
	a = -temp_a;
	b = -temp_b;
	_a = temp_a;
	_b = temp_b;
	f = (Dist_ob.dFB_dist - dS0)*1000;//换算成毫米
}


//***********************************
//BF矩阵 调用上面的函数
//***********************************
void Do::Adjustment_BF()//计算B系数阵
{
	//B.resize(iSum_Dist_obs + iSum_Angle_obs, iSum_up * 2 );
	B.resize(iSum_Dist_obs + iSum_Angle_obs, iSum_up * 2 + iAngle_Station);//定义B矩阵的大小
	B.setZero();//全部置为零
	F.resize(iSum_Dist_obs + iSum_Angle_obs,1);
	int iStation = 1;
	int iLocation = 0;
	//计算方向值
	//这段目的是为了给B方向观测的B的右上角的矩阵
	for (int i = 0; i < iSum_Angle_obs ; i++)
	{
		if (Angle_obs[i].pStation->strID != Angle_obs[iLocation].pStation->strID)
		{
			iStation++;
			iLocation = i;
		}
		double a, b, _a, _b,f;
		BF_angle_abcd(Angle_obs[i],a, b, _a, _b);//调用相应的函数 计算相应的 a,b,_a,_b;
		BF_angle_f(Angle_obs[i],f);//求对应的f
		B(i, 2 * iSum_up - 1 + iStation)=-1;//方向改正数 加-1
		//下面这段for循环作用是给B矩阵的左上角的矩阵
		for (int j = 0; j < iSum_up; j++)
		{
			if (Angle_obs[i].pStation->strID == up[j].strID)
			{
				B(i, 2 * j) = a;
				B(i, 2 * j + 1) = b;
			}
			if (Angle_obs[i].pEnd->strID == up[j].strID)
			{
				B(i, 2 * j) = _a;
				B(i, 2 * j + 1) = _b;
			}
		}
		F(i, 0) =f;
	}
	//计算边长值
	for (int i = 0; i < iSum_Dist_obs; i++)
	{
		double a, b, _a, _b, f;
		BF_dist_abcdf(Dist_obs[i],a,b,_a,_b,f);//定系数函数  并求f
		for (int j = 0; j < iSum_up; j++)
		{
			if (Dist_obs[i].pFront_id->strID == up[j].strID)//测站ID相等定个系数
			{
				B(i + iSum_Angle_obs, 2 * j) = a;
				B(i + iSum_Angle_obs, 2 * j + 1) = b;
			}
			if (Dist_obs[i].pBack_id->strID == up[j].strID)//找准站ID相等定个系数
			{
				B(i + iSum_Angle_obs, 2 * j) = _a;
				B(i + iSum_Angle_obs, 2 * j + 1) = _b;
			}

		}
		F(i + iSum_Angle_obs, 0) = f;
	}
}


//***********************************
//P矩阵
//***********************************
void Do::Adjustment_P()//计算P矩阵
{
	P.resize(iSum_Dist_obs + iSum_Angle_obs, iSum_Dist_obs + iSum_Angle_obs);//首先给矩阵全部设置为0
	for (int i = 0; i < (iSum_Dist_obs + iSum_Angle_obs ); i++)
	{
		for(int j=0;j< (iSum_Dist_obs + iSum_Angle_obs);j++)
		{
			if (i != j) { P(i, j) = 0; }
			else if(i < iSum_Angle_obs) { P(i, j) = 1; }
			else { 
				//P(i, j) = (alfa_wrong * alfa_wrong )/(length_wrong *length_wrong *Dist_obs[i - iSum_Angle_obs].dFB_dist/1000);
				P(i, j) = 100 / Dist_obs[i - iSum_Angle_obs].dFB_dist;
				double t = P(i, j);
				double k = 1;
			}
		}
	}
}
				   
//***********************************
//平差函数
//***********************************
void Do::adjustment_main()//平差主函数
{
	int tag = 0;
	MatrixXd  x;//改正数矩阵x   坐标相应改正数 测站相应改正数
	MatrixXd fe;//BT*P*F
	LinetoCString(_T("-----------------------------迭代过程-----------------------------"), strOut,EstrOut);
	do 
	{
		Adjustment_BF();
		Adjustment_P();
		Nbb = B.transpose()*P*B;
		fe = B.transpose()*P*F;
		//Nbb = B.transpose()*P*B;
		//fe = B.transpose()*P*F;
		x = Nbb.inverse()*fe;
		v = B * x - F;
		for (int i = 0; i < iSum_up; i++)
		{
			up[i].dx = up[i].dx + x(2 * i, 0) / 1000;
			up[i].dy = up[i].dy + x(2 * i + 1, 0) / 1000;
		}
		tag++;
Result.Format(_T("%s%d%s\r\n"), _T(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>迭代第\t"),tag, _T("\t次<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"));
		strOut += Result;

		for (int i = 0; i < 10; i++)
		{
			Result.Format(_T("%s\t"), _T(">>>"));
			EstrOut += Result;
		}
		Result.Format(_T("%s\t"),_T("迭代第"));
		EstrOut += Result;
		Result.Format(_T("\t%d\t\t"), tag);
		EstrOut += Result;
		Result.Format(_T("%s\t"), _T("次"));
		EstrOut += Result;
		for (int i = 0; i < 10; i++)
		{
			Result.Format(_T("%s\t"), _T("<<<"));
			EstrOut += Result;
		}
		Result.Format(_T("\n"));
		EstrOut += Result;
         //输出
		LinetoCString(_T("B矩阵"), strOut,EstrOut);
		MatrixtoCstring(B, Result, strOut,EstrOut);
		LinetoCString(_T("P矩阵"), strOut, EstrOut);
		MatrixtoCstring(P, Result, strOut, EstrOut);
		LinetoCString(_T("NBB矩阵"), strOut, EstrOut);
		MatrixtoCstring(Nbb, Result, strOut, EstrOut);
		LinetoCString(_T("x矩阵"), strOut, EstrOut);
		MatrixtoCstring(x, Result, strOut, EstrOut);
		LinetoCString(_T("F矩阵"), strOut, EstrOut);
		MatrixtoCstring(F, Result, strOut, EstrOut);
		LinetoCString(_T("v矩阵"), strOut, EstrOut);
		MatrixtoCstring(v, Result, strOut, EstrOut);
	} while (tag<10);
	Adjustment_accuracy();
}


//***********************************
//精度评定
//***********************************
void Do::Adjustment_accuracy()//精度评定
{
	Qxx = Nbb.inverse();
	double dVzero = 0;
	
	for (int i = 0; i < iSum_Angle_obs; i++)
	{
		if (Angle_obs[i].ObsAngel(DEG) < 1e-6)
		{
			dVzero = v(i, 0);
		}
		v(i, 0) -= dVzero;
	}
	MatrixXd r;
	r = v.transpose()*P*v;//VT*P*V   单位权中误差
	r0 = sqrt(r(0, 0) / (iSum_Angle_obs + iSum_Dist_obs - 2 * iSum_up - iAngle_Station));//中误差计算
    //全方位元素评定
	for (int i = 0; i < iSum_up; i++)
	{
		//Q矩阵元素抠出
		double temp_Qx = Qxx(2 * i, 2 * i);
		double temp_Qy = Qxx(2 * i + 1, 2 * i + 1);
		double temp_Qxy = Qxx(2 * i, 2 * i + 1);
		//计算点位误差
		up[i].dmx = r0 * sqrt(Qxx(2 * i, 2 * i));
		up[i].dmy = r0 * sqrt(Qxx(2 * i + 1, 2 * i + 1));
		up[i].dmk = sqrt(up[i].dmx*up[i].dmx + up[i].dmy*up[i].dmy);
		//计算误差椭圆相应参数
		double temp_K = sqrt((temp_Qx - temp_Qy)*(temp_Qx - temp_Qy) + 4 * temp_Qxy*temp_Qxy);
	    double temp_dQe = 0.5*(temp_Qx + temp_Qy + temp_K);
		double temp_dQf = 0.5*(temp_Qx + temp_Qy - temp_K);
		up[i].dE = r0 * sqrt(temp_dQe);
		up[i].dF = r0 * sqrt(temp_dQf);
		up[i].dQ = atan((temp_dQe - temp_Qx) / temp_Qxy);
		up[i].dQ = up[i].dQ > 0 ? up[i].dQ : up[i].dQ + 2 * PI;//存储为弧度制
	}
}



//***********************************
//输出函数
//***********************************
void Do::out()
{

	//初始化
	LinetoCString(_T("----------------------------原始数据----------------------------"), strOut,EstrOut);
	LinetoCString(_T("已知点ID\tX\tY"), strOut,EstrOut);
	//输出已知点
	for (int i = 0; i < iSum_cp; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\r\n"), cp[i].strID, cp[i].dx, cp[i].dy);
		strOut += Result;
	}
	Result.Format(_T("%s\t%s%f\r\n"), _T("角度观测值误差(s):"), _T("±"), alfa_wrong);
	strOut += Result;
	Result.Format(_T("%s\t%s%f\r\n"), _T("边长观测值误差(m):"), _T("±"), length_wrong);
	strOut += Result;

	for (int i = 0; i < iSum_cp; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\n"), cp[i].strID, cp[i].dx, cp[i].dy);
		EstrOut += Result;
	}
	Result.Format(_T("%s\t%s%f\n"), _T("角度观测值误差(s):"), _T("±"),alfa_wrong);
	EstrOut += Result;
	Result.Format(_T("%s\t%s%f\n"), _T("边长观测值误差(m):"), _T("±"), length_wrong);
	EstrOut += Result;
	
	//精度评定环节
	//方向观测
	LinetoCString(_T("----------------------------方向观测成果表----------------------------"), strOut, EstrOut);
	LinetoCString(_T("测站\t找准\t方向值(dms)\t改正数(s)\t改正后的值\t"), strOut, EstrOut);
	for (int i = 0; i < iSum_Angle_obs; i++)
	{
		Result.Format(_T("%s\t%s\t%.6f\t%.6f\t%.6f\r\n"),
			Angle_obs[i].pStation->strID,
			Angle_obs[i].pEnd->strID,
			Angle_obs[i].ObsAngel(DMS),
			v(i, 0),
			Angle_obs[i].ObsAngel(DMS) + v(i, 0) / 1000
		);
			strOut += Result;
	}
	for (int i = 0; i < iSum_Angle_obs; i++)
	{
		Result.Format(_T("%s\t%s\t%.6f\t%.6f\t%.6f\n"),
			Angle_obs[i].pStation->strID,
			Angle_obs[i].pEnd->strID,
			Angle_obs[i].ObsAngel(DMS),
			v(i, 0),
			Angle_obs[i].ObsAngel(DMS) + v(i, 0) / 1000
		);
		EstrOut += Result;
	}

	LinetoCString(_T("----------------------------距离观测成果表----------------------------"), strOut,EstrOut);
	LinetoCString(_T("测站\t照准\t距离观测值(m)\t改正数(m)\t平差后值(m)\t方位角(dms)"), strOut, EstrOut);
	for (int i = 0; i < iSum_Dist_obs; i++)
	{
		Result.Format(_T("%s\t%s\t%.4f\t%.4f\t%.4f\t%.6f\r\n"),
			Dist_obs[i].pFront_id->strID,
			Dist_obs[i].pBack_id->strID,
			Dist_obs[i].dFB_dist,
			v(i+ iSum_Angle_obs, 0)/1000,
			Dist_obs[i].dFB_dist + v(i + iSum_Angle_obs, 0) / 1000,
			Angle(Process_Rad(Dist_obs[i].pFront_id->dx, Dist_obs[i].pFront_id->dy, Dist_obs[i].pBack_id->dx, Dist_obs[i].pBack_id->dy), RAD)(DMS)
		);
		strOut += Result;
	}
	for (int i = 0; i < iSum_Dist_obs; i++)
	{
		Result.Format(_T("%s\t%s\t%.4f\t%.4f\t%.4f\t%.6f\n"),
			Dist_obs[i].pFront_id->strID,
			Dist_obs[i].pBack_id->strID,
			Dist_obs[i].dFB_dist,
			v(i + iSum_Angle_obs, 0) / 1000,
			Dist_obs[i].dFB_dist + v(i + iSum_Angle_obs, 0) / 1000,
			Angle(Process_Rad(Dist_obs[i].pFront_id->dx, Dist_obs[i].pFront_id->dy, Dist_obs[i].pBack_id->dx, Dist_obs[i].pBack_id->dy), RAD)(DMS)
		);
		EstrOut += Result;
	}

	LinetoCString(_T("----------------------------平面点位误差表----------------------------"), strOut, EstrOut);
	LinetoCString(_T("点名\t长轴(m)\t短轴(m)\t长轴方位(dms)\t点位中误差(m)"), strOut, EstrOut);
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\t%.6f%s%.6f\t%.4f\r\n"), up[i].strID, up[i].dE*2/1000, up[i].dF * 2/1000, Angle(up[i].dQ, RAD)(DMS),_T("或"), Angle(up[i].dQ, RAD)(DMS) >180? Angle(up[i].dQ, RAD)(DMS) -180: Angle(up[i].dQ, RAD)(DMS)+180,up[i].dmk/1000);
		strOut += Result;
	}
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\t%.6f%s%.6f\t%.4f\n"), up[i].strID, up[i].dE * 2 / 1000, up[i].dF * 2 / 1000, Angle(up[i].dQ, RAD)(DMS), _T("或"), Angle(up[i].dQ, RAD)(DMS) > 180 ? Angle(up[i].dQ, RAD)(DMS) - 180 : Angle(up[i].dQ, RAD)(DMS) + 180, up[i].dmk / 1000);
		EstrOut += Result;
	}


	//输出控制点成果
	LinetoCString(_T("-----------------------------控制点成果表-----------------------------"), strOut,EstrOut);
	LinetoCString(_T("点名\tX(m)\tY(m)"), strOut, EstrOut);
	for (int i = 0; i < iSum_cp; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\r\n"), cp[i].strID, cp[i].dx, cp[i].dy);
		strOut += Result;
	}
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\r\n"), up[i].strID, up[i].dx, up[i].dy);
		strOut += Result;
	}
	for (int i = 0; i < iSum_cp; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\n"), cp[i].strID, cp[i].dx, cp[i].dy);
		EstrOut += Result;
	}
	for (int i = 0; i < iSum_up; i++)
	{
		Result.Format(_T("%s\t%.4f\t%.4f\n"), up[i].strID, up[i].dx, up[i].dy);
		EstrOut += Result;
	}

	//----------
		//输出B矩阵
	LinetoCString(_T("-----------------------------最后迭代 平差过程-----------------------------"), strOut, EstrOut);
	LinetoCString(_T("B矩阵"), strOut, EstrOut);
	MatrixtoCstring(B, Result, strOut, EstrOut);
	//输出P矩阵
	LinetoCString(_T("P矩阵"), strOut, EstrOut);
	MatrixtoCstring(P, Result, strOut, EstrOut);
	//输出F矩阵
	LinetoCString(_T("F矩阵"), strOut, EstrOut);
	MatrixtoCstring(F, Result, strOut, EstrOut);
	//输出v矩阵
	LinetoCString(_T("v矩阵"), strOut, EstrOut);
	MatrixtoCstring(v, Result, strOut, EstrOut);
	//输出Qxx矩阵
	LinetoCString(_T("Qxx矩阵"), strOut, EstrOut);
	MatrixtoCstring(Qxx, Result, strOut, EstrOut);
	AfxMessageBox(_T("数据已成功录入!"));
}


//***********************************
//求最大最小值
//***********************************
double Do::Min1_max2_x(Data_P *cp, int iSum_cp, int tag)//
{
	double temp=cp[0].dx;
	if (tag == 2)//返回最大值
	{
		for (int i = 0; i < iSum_cp-1; i++)
		{
			if (cp[i + 1].dx > temp)
			{
				temp = cp[i + 1].dx;
			}
		}
	}
	else if (tag == 1)//返回最小值
	{
		for (int i = 0; i < iSum_cp - 1; i++)
		{
			if (cp[i + 1].dx < temp)
			{
				temp = cp[i + 1].dx;
			}
		}
	}
	return temp;
}

//***********************************
//求最大最小值
//***********************************
double Do::Min1_max2_y(Data_P *cp, int iSum_cp, int tag)//
{
	double temp = cp[0].dy;
	if (tag == 2)//返回最大值
	{
		for (int i = 0; i < iSum_cp - 1; i++)
		{
			if (cp[i + 1].dy > temp)
			{
				temp = cp[i + 1].dy;
			}
		}
	}
	else if (tag == 1)
	{
		for (int i = 0; i < iSum_cp - 1; i++)
		{
			if (cp[i + 1].dy < temp)
			{
				temp = cp[i + 1].dy;
			}
		}
	}
	return temp;
}

//***********************************
//画三角形
//***********************************
void Do::Draw_tri(CDC* pDC,double x, double y,double length,double a)
{
	double  l = length / sqrt(3)*0.5*a;
	CPen pen;
	pen.CreatePen(PS_SOLID, 1.8, RGB(123, 25, 123));//实线画笔
	CPen *pOldPen;
	pOldPen = pDC->SelectObject(&pen);
	pDC->MoveTo(x - sqrt(3)*l, y + l);
	pDC->LineTo(x + sqrt(3)*l, y + l);
	pDC->LineTo(x , y - 2*l);
	pDC->LineTo(x - sqrt(3)*l, y + l);
}

//***********************************
//旋转 平移
//***********************************
void Do::Draw_ro(double &x, double &y, double alfa,CRect &rect,double dx,double dy,double ro1,double ro2)
{
	x = x - (rect.bottom - rect.top) / 2;
	y = y - (rect.right - rect.left) / 2;
	MatrixXd Mpoint(3, 1);
	Mpoint << x,
		y,
		1;
	MatrixXd Mro(3, 3);//旋转矩阵
	Mro << cos(alfa), -sin(alfa), 0,
		sin(alfa), cos(alfa), 0,
		0, 0, 1;
	MatrixXd Mro1(3, 3);//平移矩阵
	Mro1 <<1, 0, dx,
		0, 1,dy ,
		0, 0, 1.000;
	MatrixXd Mro2(3, 3);//绕纵、横轴旋转矩阵
	Mro2 << 1,ro2, 0,
		ro1, 1, 0,
		0, 0, 1.000;
	MatrixXd Mro3(3, 3);//绕纵、横轴旋转矩阵
	Mro3 << 1, 0, 0,
		0, 1, 0,
		0, 0, 1.000;
	Mpoint = Mro3* Mro2*Mro1*Mro * Mpoint;
	x = Mpoint(0, 0) + (rect.bottom - rect.top) / 2;
	y= Mpoint(1, 0) + (rect.right - rect.left) / 2;
}


//***********************************
//画图函数
//***********************************
void Do::draw(CDC* pDC, CRect rect, double coefficient, double alfa, double dx, double dy, double ro1, double ro2)//画图
{
	alfa = alfa * PI / 180;//对输入角度转换
	CPen pen;//定义画笔
	pen.CreatePen(PS_SOLID, 3, RGB(255, 255, 255));//实线画笔 白色的
	CPen *pOldPen;//定义一个画笔来接收
	pOldPen = pDC->SelectObject(&pen);
	int zero_x1 = 0;//矩形框的左上角元素x   计算机坐标系
	int zero_y1 = 0;//矩形框的左上角元素y
	int zero_x2 = rect.Width() - 25;//矩形框的右下角元素x
	int zero_y2 = rect.Height()-138; //矩形框的右下角元素y
	//鲁棒性检查
	if (cp == NULL) { AfxMessageBox(_T("您未输入数据!")); }
	else {
		pDC->Rectangle(zero_x1, zero_y1, zero_x2, zero_y2);
		CPen pen;
		pen.CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0));//实线画笔
		CPen *pOldPen;
		pOldPen = pDC->SelectObject(&pen);
		//double coefficient = 0.2;//缩放系数为0.8
		double axis_y = coefficient * (zero_x2 - zero_x1);//y坐标轴长度
		double axis_x = coefficient * (zero_y2 - zero_y1);//x坐标轴长度
		double Xmin, Xmax; double Ymin, Ymax;
		//判断X最小值 Y最大值
		Xmin = (Min1_max2_x(cp, iSum_cp, 1) > Min1_max2_x(up, iSum_up, 1)) ? Min1_max2_x(up, iSum_up, 1) : Min1_max2_x(cp, iSum_cp, 1);
		Ymin = (Min1_max2_y(cp, iSum_cp, 1) > Min1_max2_y(up, iSum_up, 1)) ? Min1_max2_y(up, iSum_up, 1) : Min1_max2_y(cp, iSum_cp, 1);
		Xmax = (Min1_max2_x(cp, iSum_cp, 2) < Min1_max2_x(up, iSum_up, 2)) ? Min1_max2_x(up, iSum_up, 2) : Min1_max2_x(cp, iSum_cp, 2);
		Ymax = (Min1_max2_y(cp, iSum_cp, 2) < Min1_max2_y(up, iSum_up, 2)) ? Min1_max2_y(up, iSum_up, 2) : Min1_max2_y(cp, iSum_cp, 2);
		double x0 = zero_y2 - (1 - coefficient)*0.5*(zero_y2 - zero_y1)-dx;
		double y0 = zero_x1 + (1 - coefficient)*0.6*(zero_x2 - zero_x1)+25;//起始坐标 原点
		//double y0 = zero_x1 + (1 - coefficient)*0.5*(Ymax - Ymin);//起始坐标 原点
		CString str;//原点
		str.Format(_T("%.f  %.f"), Xmin - 75, Ymin);
		double temp_01 = y0 - 75;
		double temp_02 = x0 + 20;
		Draw_ro(temp_01, temp_02, alfa, rect, dx, dy, ro1, ro2);
		pDC->TextOut(temp_01, temp_02, str);
		double coefficient2 = ((Xmax - Xmin) > (Ymax - Ymin)) ? ((Xmax - Xmin) / axis_x) : ((Ymax - Ymin) / axis_y);//这次是实际坐标投影至图中的系数
		//绘制X轴
		double temp_x001 = y0;
		double temp_x002 = y0;
		double temp_x003 = y0;
		double temp_x004 = y0 - 7;
		double temp_x005 = y0;
		double temp_x006 = y0 + 7;
		double temp_x007 = y0 - 10;
		double temp_y001 = x0;
		double temp_y002 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1);
		double temp_y003 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1);
		double temp_y004 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1) + 7;
		double temp_y005 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1);
		double temp_y006 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1) + 7;
		double temp_y007 = x0 - (0.25 + 0.75*coefficient)*(zero_y2 - zero_y1) - 20;
		Draw_ro(temp_x001, temp_y001, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x002, temp_y002, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x003, temp_y003, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x004, temp_y004, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x005, temp_y005, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x006, temp_y006, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x007, temp_y007, alfa, rect, dx, dy, ro1, ro2);
		pDC->MoveTo(temp_x001, temp_y001);
		pDC->LineTo(temp_x002, temp_y002);
		pDC->MoveTo(temp_x003, temp_y003);
		pDC->LineTo(temp_x004, temp_y004);
		pDC->MoveTo(temp_x005, temp_y005);
		pDC->LineTo(temp_x006, temp_y006);
		pDC->TextOut(temp_x007, temp_y007, _T("X"));
		//绘制Y轴
		temp_x001 = y0;
		temp_x002 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1);
		temp_x003 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1);
		temp_x004 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1) - 7;
		temp_x005 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1);
		temp_x006 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1) - 7;
		temp_x007 = y0 + (0.25 + 0.75*coefficient)*(zero_x2 - zero_x1);
		temp_y001 = x0;
		temp_y002 = x0;
		temp_y003 = x0;
		temp_y004 = x0 - 7;
		temp_y005 = x0;
		temp_y006 = x0 + 7;
		temp_y007 = x0 + 5;
		Draw_ro(temp_x001, temp_y001, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x002, temp_y002, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x003, temp_y003, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x004, temp_y004, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x005, temp_y005, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x006, temp_y006, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x007, temp_y007, alfa, rect, dx, dy, ro1, ro2);
		pDC->MoveTo(temp_x001, temp_y001);
		pDC->LineTo(temp_x002, temp_y002);
		pDC->MoveTo(temp_x003, temp_y003);
		pDC->LineTo(temp_x004, temp_y004);
		pDC->MoveTo(temp_x005, temp_y005);
		pDC->LineTo(temp_x006, temp_y006);
		pDC->TextOut(temp_x007, temp_y007, _T("Y"));
		//画平行Y轴的刻度
int tag_x = 5;//5条线
		double temp_tag_x = axis_x / tag_x;
		double temp_x = temp_tag_x;
		for (int i = 0; i < 5; i++)
		{
			double t_x = y0;
			double t_y = x0 - temp_x;
			double t_x2 = y0 + axis_y;
			double t_y2 = x0 - temp_x;
			Draw_ro(t_x, t_y, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2, t_y2, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(t_x, t_y);
			pDC->LineTo(t_x2, t_y2);
			CString str;
			str.Format(_T("%.f"), Xmin + (i + 1)*(Xmax - Xmin) / 5);
			double t_x3 = y0 - 75;
			double t_y3 = x0 - temp_x;
			Draw_ro(t_x3, t_y3, alfa, rect, dx, dy, ro1, ro2);
			pDC->TextOut(t_x3, t_y3, str);
			temp_x += temp_tag_x;
		}
		//画平行X轴的刻度
		int tag_y = 5;//5条线
		double temp_tag_y = axis_y / tag_y;
		double temp_y = temp_tag_y;
		for (int i = 0; i < 5; i++)
		{
			double t_x = y0 + temp_y;
			double t_y = x0;
			double t_x2 = y0 + temp_y;
			double t_y2 = x0 - axis_y;
			Draw_ro(t_x, t_y, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2, t_y2, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(t_x, t_y);
			pDC->LineTo(t_x2, t_y2);
			CString str;
			str.Format(_T("%.f"), Ymin + (i + 1)*(Ymax - Ymin) / 5);
			double t_x3 = y0 + temp_y;
			double t_y3 = x0 + 20;
			Draw_ro(t_x3, t_y3, alfa, rect, dx, dy, ro1, ro2);
			pDC->TextOut(t_x3, t_y3, str);
			temp_y += temp_tag_y;
		}

		//画方向观测值之间的线段
		for (int i = 0; i < iSum_Angle_obs; i++)
		{
			//srand((unsigned)time(NULL));
			
			CPen pen;
			pen.CreatePen(PS_SOLID, 0.8, RGB(255, 0, 0));//实线画笔
			CPen *pOldPen;
			pOldPen = pDC->SelectObject(&pen);
		
			double t_x = (Angle_obs[i].pStation->dy - Ymin) / coefficient2 + y0;
			double t_y = x0 - (Angle_obs[i].pStation->dx - Xmin) / coefficient2;
			double t_x2 = (Angle_obs[i].pEnd->dy - Ymin) / coefficient2 + y0;
			double t_y2 = x0 - (Angle_obs[i].pEnd->dx - Xmin) / coefficient2;
			Draw_ro(t_x, t_y, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2, t_y2, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(t_x, t_y);
			pDC->LineTo(t_x2, t_y2);

			pen.DeleteObject();

		}

		//画未知点之间的线段
		for (int i = 0; i < iSum_Dist_obs; i++)
		{
			//srand((unsigned)time(NULL));
			int a = (rand() % 200);
			int b = (rand() % 200 + 99);
			int c = (rand() % 200) - 50;
			if (a > 100 || a < 0)
			{
				a = 255;
			}
			if (b > 255 || b < 0)
			{
				b = 88;
			}
			if (c > 255 || c < 0)
			{
				c = 188;
			}
			CPen pen;
			pen.CreatePen(PS_DASHDOT, 2, RGB(a, b, c));//实线画笔
			CPen *pOldPen;
			pOldPen = pDC->SelectObject(&pen);


			double t_x = (Dist_obs[i].pFront_id->dy - Ymin) / coefficient2 + y0;
			double t_y = x0 - (Dist_obs[i].pFront_id->dx - Xmin) / coefficient2;
			double t_x2 = (Dist_obs[i].pBack_id->dy - Ymin) / coefficient2 + y0;
			double t_y2 = x0 - (Dist_obs[i].pBack_id->dx - Xmin) / coefficient2;
			
			Draw_ro(t_x, t_y, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2, t_y2, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(t_x, t_y);
			pDC->LineTo(t_x2, t_y2);

			pen.DeleteObject();//释放资源

		}

		//画已知点之间的线段
		for (int i = 0; i < iSum_cp - 1; i++)
		{
			//srand((unsigned)time(NULL));
			int a = (rand() % 200);
			int b = (rand() % 200 + 99);
			int c = (rand() % 200) - 50;
			if (a > 100 || a < 0)
			{
				a = 255;
			}
			if (b > 255 || b < 0)
			{
				b = 88;
			}
			if (c > 255 || c < 0)
			{
				c = 188;
			}
			CPen pen;
			pen.CreatePen(PS_SOLID, 1, RGB(a, b, c));//实线画笔
			CPen *pOldPen;
			pOldPen = pDC->SelectObject(&pen);

			double t_x = (cp[i].dy - Ymin) / coefficient2 + y0;
			double t_y = x0 - (cp[i].dx - Xmin) / coefficient2;
			double t_x2 = (cp[i + 1].dy - Ymin) / coefficient2 + y0;
			double t_y2 = x0 - (cp[i + 1].dx - Xmin) / coefficient2;

			double t_x_ = (cp[i].dy - Ymin) / coefficient2 + y0 + 3;
			double t_y_ = x0 - (cp[i].dx - Xmin) / coefficient2 + 3;
			double t_x2_ = (cp[i + 1].dy - Ymin) / coefficient2 + y0 + 3;
			double t_y2_ = x0 - (cp[i + 1].dx - Xmin) / coefficient2 + 3;

			Draw_ro(t_x, t_y, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2, t_y2, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x_, t_y_, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(t_x2_, t_y2_, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(t_x, t_y);
			pDC->LineTo(t_x2, t_y2);
			pDC->MoveTo(t_x_, t_y_);
			pDC->LineTo(t_x2_, t_y2_);

			pen.DeleteObject();

		}
         double coefficient3 = (0.8 / coefficient) *(up[0].dE) / 20;//比例系数
		for (int i = 0; i < iSum_up; i++)
		{
			int a = (rand() % 200);
			int b = (rand() % 200 + 99);
			int d = (rand() % 200) - 50;
			if (a > 100 || a < 0)
			{
				a = 255;
			}
			if (b > 255 || b < 0)
			{
				b = 88;
			}
			if (d > 255 || d < 0)
			{
				d = 188;
			}
			CPen pen;
			pen.CreatePen(PS_SOLID, 1.8, RGB(a, b, d));//实线画笔
			CPen *pOldPen;
			pOldPen = pDC->SelectObject(&pen);
			for (int j = 0; j < 120; j += 3)
			{
				//画椭圆
				double dAlf = j * 2 * PI / 120;
				double xae, ybf;
				double c = 0;
				double tralatazi;
				xae = up[i].dE / coefficient3 * cos(dAlf);
				ybf = up[i].dF / coefficient3 * sin(dAlf);
				tralatazi = up[i].dQ+PI/2;
				//tralatazi = up[i].dQ ;
				double temp_1 = xae * cos(tralatazi) + ybf * sin(tralatazi) + (up[i].dy - Ymin) / coefficient2 + y0;
				double temp_2 = -ybf * cos(tralatazi) + xae * sin(tralatazi) + x0 - (up[i].dx - Xmin) / coefficient2;
				Draw_ro(temp_1, temp_2, alfa, rect, dx, dy, ro1, ro2);
				if (j == 0) { pDC->MoveTo(temp_1, temp_2); }
				pDC->LineTo(temp_1, temp_2);
			}

			double temp1 = (up[i].dy - Ymin) / coefficient2 + y0 + (up[i].dF*sin(up[i].dQ+PI/2)) / coefficient3;//长轴右上角 x
			double temp2 = x0 - (up[i].dx - Xmin) / coefficient2 - (up[i].dF*cos(up[i].dQ+PI/2)) / coefficient3;//长轴右上角 y
			double temp3 = (up[i].dy - Ymin) / coefficient2 + y0 - (up[i].dF*sin(up[i].dQ+PI/2) )/ coefficient3;//长轴左下角 x
			double temp4 = x0 - (up[i].dx - Xmin) / coefficient2 + (up[i].dF*cos(up[i].dQ+PI/2) )/ coefficient3;//长轴左下角 y
			Draw_ro(temp1, temp2, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(temp3, temp4, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(temp1, temp2);
			pDC->LineTo(temp3, temp4);
			pen.DeleteObject();

			double _temp1 = (up[i].dy - Ymin) / coefficient2 + y0 + (up[i].dE*cos(up[i].dQ + PI / 2)) / coefficient3;//短轴右下角 x
			double _temp2 = x0 - (up[i].dx - Xmin) / coefficient2 + (up[i].dE*sin(up[i].dQ + PI / 2)) / coefficient3;//短轴右上角 y
			double _temp3 = (up[i].dy - Ymin) / coefficient2 + y0 - (up[i].dE*cos(up[i].dQ + PI / 2)) / coefficient3;//短轴左上角 x
			double _temp4 = x0 - (up[i].dx - Xmin) / coefficient2 - (up[i].dE*sin(up[i].dQ + PI / 2)) / coefficient3;//短轴左上角 y
			Draw_ro(_temp1, _temp2, alfa, rect, dx, dy, ro1, ro2);
			Draw_ro(_temp3, _temp4, alfa, rect, dx, dy, ro1, ro2);
			pDC->MoveTo(_temp1, _temp2);
			pDC->LineTo(_temp3, _temp4);

		}
		//画ID
		for (int i = 0; i < iSum_up; i++)
		{
			CString str;
			str.Format(_T("%s"), up[i].strID);

			double temp_1 = (up[i].dy - Ymin) / coefficient2 + y0;
			double temp_2 = x0 - (up[i].dx - Xmin) / coefficient2;
			Draw_ro(temp_1, temp_2, alfa, rect, dx, dy, ro1, ro2);
			pDC->TextOut(temp_1, temp_2, str);
		}
		for (int i = 0; i < iSum_cp; i++)
		{
			CString str;
			str.Format(_T("%s"), cp[i].strID);
			double temp_1 = (cp[i].dy - Ymin) / coefficient2 + y0;
			double temp_2 = x0 - (cp[i].dx - Xmin) / coefficient2;
			Draw_ro(temp_1, temp_2, alfa, rect, dx, dy, ro1, ro2);
			Draw_tri(pDC, temp_1, temp_2, 50, coefficient / 0.8);
			pDC->TextOut(temp_1, temp_2, str);
		}
		//画比例尺
		double ruler = axis_y * 500 / (Ymax - Ymin);//图上长度代表实际500M
		temp_x001 = (zero_x1 + zero_x2) / 2 - ruler / 2;
		temp_x002 = (zero_x1 + zero_x2) / 2 - ruler / 2;
		temp_x003 = (zero_x1 + zero_x2) / 2 + ruler / 2;
		temp_x004 = (zero_x1 + zero_x2) / 2 + ruler / 2;
		temp_x005 = (zero_x1 + zero_x2) / 2;

		temp_y001 = 20;
		temp_y002 = 23;
		temp_y003 = 23;
		temp_y004 = 20;
		temp_y005 = 26;

		Draw_ro(temp_x001, temp_y001, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x002, temp_y002, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x003, temp_y003, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x004, temp_y004, alfa, rect, dx, dy, ro1, ro2);
		Draw_ro(temp_x005, temp_y005, alfa, rect, dx, dy, ro1, ro2);

		pDC->MoveTo(temp_x001, temp_y001);
		pDC->LineTo(temp_x002, temp_y002);
		pDC->LineTo(temp_x003, temp_y003);
		pDC->LineTo(temp_x004, temp_y004);


		pDC->TextOut(temp_x005, temp_y005, _T("1:500"));
	}
}


//***********************************
//导出数据到excel中
//***********************************
void Do::ReportExcel()
{
	if (strOut == _T("")) { AfxMessageBox(_T("请先输入数据!")); }
	else {
		CString strPath;
		CFileDialog dlg(false, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Excel Files(*.xls)|*.xls|All Files(*.*)|*.*|"), AfxGetMainWnd());
		if (dlg.DoModal() == IDCANCEL) return;
		else
		{
			strPath = dlg.GetPathName();
			if (strPath.Find(_T(".xls")) < 0)
			{
				strPath += _T(".xls");
			}
		}
		TRY
		{
			CString cs;
			CStdioFile file(strPath, CFile::shareExclusive | CFile::modeWrite | CFile::modeCreate);
			setlocale(LC_CTYPE, ("chs")); //设置中文输出
			file.WriteString(EstrOut);
			file.Close();
			CString temp;
			temp.Format(_T("%s%s"),  _T("已导出至"),strPath);
			AfxMessageBox(temp);
		}
			CATCH_ALL(e)
		{
			e->ReportError();
			return;
		}
		END_CATCH_ALL
	}
}

//***********************************
//导出数据到txt dat中
//***********************************
void Do::Reporttxt()
{
	if (EstrOut == _T("")) { AfxMessageBox(_T("请先输入数据!")); }
	else {
		CFileDialog dlg(false, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Txt Files(*.txt)|*.txt|All Files(*.*)|*.*|"), AfxGetMainWnd());
		CString strPath;
		if (dlg.DoModal() == IDCANCEL) return;
		else
		{
			strPath = dlg.GetPathName();

			if (strPath.Find(_T(".txt")) < 0)
			{
				if (strPath.Find(_T(".dat")) < 0)
				{
					strPath += _T(".txt");//默认储存为txt模式
				}
			}
		}
		TRY
		{
			CString cs;
			CStdioFile file(strPath, CFile::shareExclusive | CFile::modeWrite | CFile::modeCreate);
			setlocale(LC_CTYPE, ("chs")); //设置中文输出
			file.WriteString(strOut);
			file.Close();
			CString temp;
			temp.Format(_T("%s%s"),  _T("已导出至"),strPath);
			AfxMessageBox(temp);
		}
			CATCH_ALL(e)
		{
			e->ReportError();
			return;
		}
		END_CATCH_ALL
	}
}

5.10 文件 < CTraversenetwork10zrxDlg.cpp>部分代码

//对话框所在类
#include "stdafx.h"
#include "Traverse_network_10_zrx.h"
#include "Traverse_network_10_zrxDlg.h"
#include "afxdialogex.h"
#include "do.h"
#include"DrawEx.h"
#include"DrawSup.h"
#include "Helpyou.h"
//…
Do k;//在.h文件中
int tag=0;
//按钮 导入数据 ( txt或dat)
void CTraversenetwork10zrxDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
 	UpdateData(TRUE);
	out = ":)";
	k.strOut=":)";

	tag = k.read();
	if ( tag== 1)
	{
		k.estimate();
		k.adjustment_main();
		k.out();
		out = k.strOut;
		
	}
	UpdateData(FALSE);
}

//按钮 退出
void CTraversenetwork10zrxDlg::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnCancel();
}

//按钮 画图
void CTraversenetwork10zrxDlg::OnBnClickedButton1draw()
{
	// TODO: 在此添加控件通知处理程序代码
	if (tag == 1)
	{
		DrawEx dui;
		dui.d = k;
		dui.DoModal();
	}
	else AfxMessageBox(_T("请输入数据"));	
}

//按钮 帮助
void CTraversenetwork10zrxDlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	Helpyou  h;
	h.DoModal();
}



//按钮 导出 txt 或 dat 
void CTraversenetwork10zrxDlg::OnBnClickedButton3()//输出至txt
{
	// TODO: 在此添加控件通知处理程序代码
	if (tag == 1)
	{
		k.Reporttxt();
	}
	else AfxMessageBox(_T("请输入数据"));
}

//按钮 导出excel
void CTraversenetwork10zrxDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	if (tag == 1)
	{ 
	k.ReportExcel();
	}
	else AfxMessageBox(_T("请输入数据"));
}


void CTraversenetwork10zrxDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	if (tag == 1)
	{
		DrawSup dui;
		dui.d = k;
		dui.DoModal();
	}
	else AfxMessageBox(_T("请输入数据"));
}

5.11 文件 < DrawEx .h>

//对话框所在类
#pragma once
#include"Do.h"
// DrawEx 对话框
class DrawEx : public CDialogEx
{
	DECLARE_DYNAMIC(DrawEx)

public:
	DrawEx(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~DrawEx();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_DrawEx };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
public:
	Do d;
	double coefficient;
	double alfa;
	double dx;
	double dy;
	double roi1;
	double roi2;
	double tag1;
	afx_msg void OnBnClickedOk2();
	afx_msg void OnSize(UINT nType, int cx, int cy);
};

5.12 文件 < DrawEx .cpp>

#include "stdafx.h"
#include "Traverse_network_10_zrx.h"
#include "DrawEx.h"
#include "afxdialogex.h"
//按钮 二维画图
void DrawEx::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
	UpdateData(TRUE);
	CDC* pDC = GetDlgItem(IDC_STATIC)->GetDC();
	GetDlgItem(IDC_STATIC)->UpdateWindow();
	CRect rc;
	GetDlgItem(IDC_STATIC)->GetWindowRect(&rc);
	GetWindowRect(&rc);
	if (tag1 != 0) { AfxMessageBox(_T(错误")); }
	d.draw(pDC, rc, coefficient, alfa,-dx,-dy,roi1,roi2);
	UpdateData(FALSE);
}

//按钮 三维画图
void DrawEx::OnBnClickedOk2()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	CDC* pDC = GetDlgItem(IDC_STATIC)->GetDC();
	GetDlgItem(IDC_STATIC)->UpdateWindow();
	CRect rc;
	GetDlgItem(IDC_STATIC)->GetWindowRect(&rc);
	GetWindowRect(&rc);
	d.draw(pDC, rc, coefficient-0.35, alfa-15,-dx+200, -(dy-200), roi1+0.1, roi2+0.8);
	UpdateData(FALSE);
}

5.11 控件ID及其属性

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第28张图片
《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第29张图片

六、计划与总结

6.1 时间计划安排

《测绘程序开发实习》导线网平差 C++上机实验报告 CSU_第30张图片

6.2 感想及总结

暂且让我以每天记日记的方法写下自己的设计心程。我希望这些能够帮助处理某些过程遇到的bug,怎样克服。当然能不看就不看,干就完了。
2019年中旬进行,2020年1月整理上传。

7月1日

这天是听报告、做计划的一天,是较为轻松的一天。
这次的报告比较的大的收获之一就是,解决了上次考试的指针的使用(float swap(float *a, float &b),为下文站点匹配做出铺垫。

7月2日

按照我昨天计划的内容,4天是能做完的。我还是比较自信自己的C++基础,于是在早上我便兴致冲冲地做了起来。
关于对话框的选择。上来要做的便是确认下对话框形式还是文档形式。这点自己还是犹豫了下,尽管在后来我做完这一切想起文档形式或许更加地直观。问了旁边的其他人,都还没定,我还是选择了经验比较多的对话框形式,事实证明这是一条群众路线,我没遇到用对话框做的人。
关于类的设计。类设计得不好,越做越难受。我参照了下以前水准网的实验,但我当时用的是ID匹配,需要加自定义的remove()函数,因为自身的读出来的整个CString字符会读入换行符。所以这次我决定使用指针。
在晚上,我初步解决了数据的读入,因为读入即需要判断指针,这相当与要将搜索函数等辅助函数写出。
同时,我选择了边读入边输出的模式,即同时将结输出至txt中,方便我查看每一步过程的bug。我选择将数据的地址返回,同一测站的地址都是一样,数据正确。
这一天,我心里很踏实的,因为已经超过了大多数同学的进度。

7月3日

我开始写概算函数。选择了《测绘程序设计基础》书上末的那段概算函数为实例。但这上午只有最后20分钟我才开始催自己写这些函数。这里,说下自己的一点感想。我远没有达到能够自己编算法的高度,只是算法的搬运工。但是要想做算法的搬运工,前提是要能理解这段代码的思想,才能驾驭这段代码为己所用。读懂代码的意思比较难,我花了一上午的时间来读懂了书中的概算的思想,我脑子才比较放心这段代码可以移入。
中午回到宿舍,我趁着上午的热度,一鼓作气将代码写出,当时才1点多。
然后我更改了输出至txt的格式。同时开始思考接下来的平差。
但是还是有点错误,晚上11点多的时候发现是一个指针未指向导致的。一个bug还是可以接受的。

7月4日

这天的早上,我检查了下无bug,可以进行下一步平差内容了。
有了前一天的经验,我就照葫芦画瓢,要想写出平差内容,脑子里要先有个框架。
这里说下我对平差中碰的比较大的一个困难是,B矩阵的理解。因为进度比较快,附近并没找到理解B矩阵的同学。作为第一个吃螃蟹的人,上面的B矩阵是我花了大量时间才懂了的,印象极其深刻。关于B矩阵右上角的iStation部分,我当时怎么也想不出来是应该赋值多少,花了好长时间才想明白,明白的同时,也对平差内容更加深刻了。
然后花了一下午BFP函数写出,解决了部分bug,程序能够正常运行。

7月5日

这天问了老师的潘老师的改正数迭代问题,由于采取的是方向值,改正数V只需改正前 位置坐标*2 的个数。
精度平定参照平差的书中部分,使用K的方法做出。
下午两点左右,我将所有部分都完整txt输出了,当然这是对较少数据的示例数据,其中还有若干bug几天后才发现。这一刻是比较兴奋的。
这天晚上,我开始着手画图的,在CSDN上搜索了一整个晚上,最后只会在主对话框画图,略微失望。

7月6日

我自己开始一步步地检索自己的bug,尽管找到了些,但对最大那份数据仍不成立。我甚至开始怀疑最大那份数据有问题,为此花了不少时间,将里面的点用展开。
下午,在解决自己最后的程序bug同时,在帮助同学解决bug。相当于过了好几遍,我也更加熟悉概算的思想。这同时我也在对照自己的程序。

7月7日

今天极其令人兴奋的一天。
同学做到平差的部分了,当然也出现了bug。万万没想到,找同学的bug同时解决了我的bug!B、P、F矩阵一一对照,尽管同学的bug是别的地方出错,我竟然发现是BF_angle_f(Data_Obsangle Angle_ob,double &f)中给F赋值时应该转成206265应该是弧度制206265,我竟然是DEG206265!
当时我在边躺床上边想,突然脑子里晃到这一处赋值代码我们不同,尽管同学的代码是别处的bug。我立马手机百度确认了下。跳下床来,换了6个字母。那份的较多数据的成了!画图结果也成功运行!
这天算是解决了所有的大bug了。

7月8日

上午图书馆,下午4**。
整整一天,我开始进行界面优化、txt格式、绘画优化。同时进行了鲁棒性检查。

7月9日

上午图书馆,下午4**。初步写了实验报告。
增加了excel形式。自定义了几个输出函数,excel中输出关键:\t是空一格 \n是另起一行。
下午又问了张老师如何解决弹出对话框画图、给子对话框添加消息函数及类之间传递信息。子对话框画在静态文本。添加消息函数是通过类向导。类之间传递信息通过声明类内对象实现。(上文有相应代码)。
这里感叹一下,一晚上百度都没解决的对话框画图问题,问老师10分钟就解决了。有困难找老师!
同时,问了问测绘同学的图像旋转。回去以后就想我画图有个最大的失误就是没把要画的点保存成矩阵。这就导致我后续给所有的点旋转时出现许多多余操作。这种重复操作,导致我改了将近一个小时,而且代码冗余。

7月10日

在给图像旋转的同时,我就想既然已经把所有点位信息都实现通过一个旋转函数旋转,为什么不用一下数字图像处理里的那种齐次坐标。所以,我定义了3×3的矩阵,来此实现图像的旋转、平移、缩放、投影等操作。
这一天进行了最后的鲁棒性检查、界面美化及编写部分课程设计报告,为明日考核做准备。

7月11日

答辩。

有以下几点的收获:
理论知识要牢固,还需要加强下C++的学习。
Debug能力较以前有很大的提升,不慌而有条理。
自己尝试过解决还解决不了的东西要像高中一样,多问问老师,老师知道很多。
不要闭门造车,和同学多多交流,比自己出色的想法要加以运用。
同学之间相互帮助,共同提升。
读程序更加顺利,学会读程序,化它为己。
写大型程序要做计划,搭框架,模块化,一一击垮,省时省力。
自己还是太菜,要好好努力,学习更多知识。同时要有自信心。

代码虽多 不要贪杯~

你可能感兴趣的:(C++,#,C++测绘程序设计基础)