- 目的要求
- 通过程序的设计深入理解解析空中三角测量的整个过程
- 提高应用程序设计语言解决问题的能力。
- 资料及用具
一台微机,一套调试程序所用的数据。
- 实习内容及作业步骤
用VB(或者C语言)程序设计语言编写单航带区域网概算的程序,具有包含一些三方面的内容:
- (一)连续法像对的相对定向
目标:求解各模型点在各模型像空间辅助坐标系中的坐标(Xi,Yi,Zi)
步骤:
- 用连续法相对定向求解相对定向元素(bx,by,bz,φ,ω,κ)。
- 用前方交会公式计算各模型点坐标。
- (二)航带网模型的建立
目标:求出航带内各模型点在航带统一坐标系(第一个像片的像空间坐标系)中的坐标(Xi‘,Yi‘,Zi‘)。
步骤:
- 根据模型间的三个公共点求解个模型的缩放系数ki
- 通过各模型缩放系数ki将模型内各模型点转换到航带统一坐标系。
- (三)模型的绝对定向
目标:求出航带内各模型点在大地坐标系中的坐标(Xti,Yti,Zti)。
步骤:
- 根据两个已知控制点确定大地坐标系与地面摄测坐标系之间的转换参数(a、b)。
- 将所有控制点的大地坐标(Xt,Yt,Zt)通过转换参数(a、b)转换为地面摄测坐标系(Xtp,Ytp,Ztp)。
- 根据已知控制点的地面摄测坐标(Xtp,Ytp,Ztp)求解绝对定向元素(ΔX,ΔY,ΔZ,Φ,Ω,Κ,λ)。
- 根据绝对定向元素(ΔX,ΔY,ΔZ,Φ,Ω,Κ,λ)将各模型点在航带统一坐标系中的坐标(Xi‘,Yi‘,Zi‘)转换为地面摄测坐标系(Xtp,Ytp,Ztp)。
- 将各模型点的地面摄测坐标(Xtp,Ytp,Ztp)通过转换参数(a、b)转换为所有控制点的大地坐标(Xt,Yt,Zt)。
- 上交成果
调试完成的程序一份及计算结果。
附:调试数据:
- 基本数据
摄影机主距:f=153.033mm
bx=200mm
- 像对坐标数据(单位:微米)
像对1: 701 702
1201 648790 735260 -230980 788550
1818 113860 595800 -771380 679190
1202 241050 586260 -644640 661950
1204 578030 223960 -327700 277590
1203 256140 187820 -648360 260160
1205 606230 -104550 -315660 -51440
1206 278340 -565020 -660020 -487200
1052 179220 -757800 -765430 -670400
410 478510 -637940 -466930 -569840
399 975930 -700850 16690 -658940
192 917380 -16160 -4600 18540
370 803150 758570 -76440 802960
1118 94870 709670 -785850 795830
194 35030 -34550 -877140 50930
-398 19790 -843710 -925660 -745370
像对2: 703 702
400 -568240 -631500 426790 -634450
1207 -601170 642970 323920 637060
399 -980300 -630600 16690 -658940
192 -963100 51030 -4600 18540
370 -989450 836700 -76410 802880
1209 -8790 641530 921460 679700------20
401 -29060 -915900 981740 -884160
-190 1460 5490 965780 38900
像对3: 703 704
1826 931930 729560 -26020 680090
402 907100 -785750 20330 -836630
1055 753660 -838360 -134160 -896670
411 397770 -725220 -500070 -791380
1211 49010 50160 -875490 -17320
188 918060 48330 -10150 11950
1225 890340 544420 -58540 499270
1210 624000 444520 -317940 392160
1209 -8690 641540 -945780 560530---------31
401 -29020 -915940 -930070 -1004070
-190 1460 5460 -921980 -63410
3、控制点数据
点号 X坐标 Y坐标 Z坐标
==================================================
1201 24204.689 46604.652 46.251
1205 24343.683 45111.263 48.198
1206 24965.047 44309.253 49.340
1209 22167.904 46432.515 46.457
4、检查点数据
点号 X坐标 Y坐标 Z坐标
==================================================
1118 25192.533 46608.059 48.936
1202 24941.046 46375.998 46.539
1203 24945.705 45662.638 49.052
1204 24369.486 45700.421 49.020
1207 23218.292 46347.142 48.993
注意:上述检查点数据、控制点数据、像对数据可能每次的不一样,本程序只适用上述数据的特定情况,并不能直接套用进行计算,但具体原理在代码中已注释,非全原创,但步骤详细清晰,均按照PPT公式进行。需要PPT的小伙伴可以在评论区留言,获取一整套摄影测量复习PPT。
代码程序(C语言):
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// 定义必要的常量和数据结构
#define f 0.153033 // 摄影机主距,单位:米
#define bx 0.200 // 基线,单位:米
typedef struct//输入 像点坐标
{
double index;
double x1;
double y1;
double x2;
double y2;
}data1;
typedef struct //输入 控制点坐标
{
double index;
double X;
double Y;
double Z;
}data3;
typedef struct //相对定向求得的像空辅
{
double index;
double X1;
double Y1;
double Z1;
double X2;
double Y2;
double Z2;
}data2;
typedef struct//像控点和像对的对应
{
double index;
double x;//左片的相同点
double y;
double z;
int dex;
}data4;
typedef struct//相对定向后利用前方交会公式求得的模型点坐标
{
double index;
double X1;
double Y1;
double Z1;
}data5;
typedef struct //检查点数据
{
double index;
double X_;
double Y_;
double Z_;
} data6;
void matrix_multiply(double* A, int A_rows, int A_cols, double* B, int B_rows, int B_cols, double* result)
{ // A的列数必须等于B的行数
if (A_cols != B_rows) {
printf("Matrix dimensions do not match for multiplication!\n");
return;
}
// 矩阵乘法计算
for (int i = 0; i < A_rows; i++) {
for (int j = 0; j < B_cols; j++) {
result[i * B_cols + j] = 0; // 初始化结果矩阵元素
for (int k = 0; k < A_cols; k++) {
result[i * B_cols + j] += A[i * A_cols + k] * B[k * B_cols + j];
}
}
}
}
#pragma region InverseMatrix
int InverseMatrix(double* B, int n, double* inverse) {
// 创建增广矩阵,将 B 扩展成 [B | I]
double* aug = (double*)malloc(n * 2 * n * sizeof(double));
if (aug == NULL) {
printf("内存分配失败\n");
return 0;
}
// 构造增广矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
aug[i * 2 * n + j] = B[i * n + j]; // 左边是矩阵 B
aug[i * 2 * n + j + n] = (i == j) ? 1.0 : 0.0; // 右边是单位矩阵 I
}
}
// 高斯-约当消元法
for (int i = 0; i < n; i++) {
// 找到当前列中绝对值最大的元素并交换行
double maxElement = fabs(aug[i * 2 * n + i]);
int maxRow = i;
for (int k = i + 1; k < n; k++) {
if (fabs(aug[k * 2 * n + i]) > maxElement) {
maxElement = fabs(aug[k * 2 * n + i]);
maxRow = k;
}
}
// 如果无法求逆(矩阵不可逆),返回错误代码
if (maxElement == 0.0) {
printf("矩阵不可逆\n");
free(aug);
return 0;
}
// 交换当前行与最大元素所在行
if (maxRow != i) {
for (int k = 0; k < 2 * n; k++) {
double temp = aug[i * 2 * n + k];
aug[i * 2 * n + k] = aug[maxRow * 2 * n + k];
aug[maxRow * 2 * n + k] = temp;
}
}
// 归一化当前行,使对角线元素变为 1
double diag = aug[i * 2 * n + i];
for (int k = 0; k < 2 * n; k++) {
aug[i * 2 * n + k] /= diag;
}
// 消去其他行的当前列
for (int j = 0; j < n; j++) {
if (j != i) {
double factor = aug[j * 2 * n + i];
for (int k = 0; k < 2 * n; k++) {
aug[j * 2 * n + k] -= factor * aug[i * 2 * n + k];
}
}
}
}
// 提取右侧的单位矩阵部分作为逆矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
inverse[i * n + j] = aug[i * 2 * n + j + n];
}
}
// 释放增广矩阵内存
free(aug);
return 1; // 成功返回 1
}
#pragma endregion
int main()
{
#pragma region import data
data1 ImageData[34];//共有34对像点 15/8/11
//导入像点坐标
FILE* file = fopen("./像点数据.csv", "r"); // 打开文件
if (!file) {
printf("无法打开文件\n");
return 1;
}
char buffer[100];
fgets(buffer, sizeof(buffer), file);// 跳过第一行(标题行)
int i = 0;
while (fscanf(file, "%lf,%lf,%lf,%lf,%lf",
&ImageData[i].index, &ImageData[i].x1, &ImageData[i].y1, &ImageData[i].x2, &ImageData[i].y2) == 5) {
ImageData[i].x1 = ImageData[i].x1 / 1000000;
ImageData[i].y1 = ImageData[i].y1 / 1000000;
ImageData[i].x2 = ImageData[i].x2 / 1000000;
ImageData[i].y2 = ImageData[i].y2 / 1000000;
i++;
if (i >= 34) break; // 确保不超过数组的大小
}
fclose(file);
for (int i = 0; i < 34; i++) { //输出读取的数据验证结果
printf("点号: %lf, 左片x: %lf, 左片y: %lf, 右片x: %lf, 右片y: %lf\n",
ImageData[i].index, ImageData[i].x1, ImageData[i].y1, ImageData[i].x2, ImageData[i].y2);
}
//导入控制点坐标
data3 ControlData[4];//共有4组控制点
FILE* file3 = fopen("./控制点数据.csv", "r"); // 打开文件
if (!file3) {
printf("无法打开文件\n");
return 1;
}
char buffer3[100];
fgets(buffer3, sizeof(buffer3), file3);// 跳过第一行(标题行)
int j = 0;
while (fscanf(file3, "%lf,%lf,%lf,%lf",
&ControlData[j].index, &ControlData[j].X, &ControlData[j].Y, &ControlData[j].Z) == 4) {
j++;
if (j >= 4) break; // 确保不超过数组的大小
}
fclose(file3);
printf("\n");
for (int j = 0; j < 4; j++) { //输出读取的数据验证结果
printf("点号: %lf, 控制点X: %lf, 控制点Y: %lf, 控制点Z: %lf\n",
ControlData[j].index, ControlData[j].X, ControlData[j].Y, ControlData[j].Z);
}
//导入检查点坐标
data6 CheckData[5];//共有4组控制点
FILE* file6 = fopen("./检查点数据.csv", "r"); // 打开文件
if (!file6) {
printf("无法打开文件\n");
return 1;
}
char buffer6[100];
fgets(buffer6, sizeof(buffer6), file6);// 跳过第一行(标题行)
int k = 0;
while (fscanf(file6, "%lf,%lf,%lf,%lf",
&CheckData[k].index, &CheckData[k].X_, &CheckData[k].Y_, &CheckData[k].Z_) == 4) {
k++;
if (k >= 5) break; // 确保不超过数组的大小
}
fclose(file6);
printf("\n");
for (int k = 0; k < 5; k++) { //输出读取的数据验证结果
printf("点号: %lf, 检查点X: %lf, 检查点Y: %lf, 检查点Z: %lf\n",
CheckData[k].index, CheckData[k].X_, CheckData[k].Y_, CheckData[k].Z_);
}
#pragma endregion
#pragma region 读取文件结束,开始相对定向----第一个像对
double result1[5] = { 0 }, result2[5] = { 0 }, result3[5] = { 0 };
int i1, i2, i3;
//投影系数
double N11[15], N21[15];
double N12[8], N22[8];
double N13[11], N23[11];
//相对定向元素
double μ1 = 0, γ1 = 0, φ21 = 0, ω21 = 0, κ21 = 0;
double μ2 = 0, γ2 = 0, φ22 = 0, ω22 = 0, κ22 = 0;
double μ3 = 0, γ3 = 0, φ23 = 0, ω23 = 0, κ23 = 0;
double a4, a5, a6, b4, b5, b6, c4, c5, c6;
data2 ImageData1[15]; data2 ImageData2[8]; data2 ImageData3[11];
double by1, bz1;
double by2, bz2;
double by3, bz3;
double A1[15][5];//误差方程——矩阵系数
double B1[5][5];
double R11[5][15];//误差方程——A的转置矩阵
double A11[5][15];//误差方程——
double Q1[15];
double BB1[5][5];//误差方程——B的逆矩阵
double A2[8][5];//误差方程——矩阵系数
double B2[5][5];//误差方程——过渡矩阵
double R12[5][8];//误差方程——A的转置矩阵
double A12[5][8];//误差方程——
double Q2[8];
double BB2[5][5];//误差方程——B的逆矩阵
double A3[11][5];
double B3[5][5];
double R13[5][11];
double A13[5][11];
double Q3[11];
double BB3[5][5];
for (i1 = 1;; i1++)//第一个文件相对定向元素
{
//初始化相对定向元素
μ1 += result1[0];
γ1 += result1[1];
φ21 += result1[2];
ω21 += result1[3];
κ21 += result1[4];
by1 = bx * μ1;
bz1 = bx * γ1;
//旋转矩阵的方向元素
double
a1 = cos(φ21) * cos(κ21) - sin(φ21) * sin(ω21) * sin(κ21),
a2 = -cos(φ21) * sin(κ21) - sin(φ21) * sin(ω21) * cos(κ21),
a3 = -sin(φ21) * cos(ω21),
b1 = cos(ω21) * sin(κ21),
b2 = cos(ω21) * cos(κ21),
b3 = -sin(ω21),
c1 = sin(φ21) * cos(κ21) + cos(ω21) * sin(ω21) * sin(κ21),
c2 = -sin(φ21) * sin(κ21) + cos(ω21) * sin(ω21) * cos(κ21),
c3 = cos(φ21) * cos(ω21);
for (int i = 0; i < 15; i++)
{
//像点的像空间辅助坐标
ImageData1[i].index = ImageData[i].index;
ImageData1[i].X1 = ImageData[i].x1;//R1=E
ImageData1[i].Y1 = ImageData[i].y1;
ImageData1[i].Z1 = -f;
ImageData1[i].X2 = a1 * ImageData[i].x2 + a2 * ImageData[i].y2 + a3 * (-f);//R2
ImageData1[i].Y2 = b1 * ImageData[i].x2 + b2 * ImageData[i].y2 + b3 * (-f);
ImageData1[i].Z2 = c1 * ImageData[i].x2 + c2 * ImageData[i].y2 + c3 * (-f);
//计算投影系数
N11[i] = (bx * ImageData1[i].Z2 - bz1 * ImageData1[i].X2) / (ImageData1[i].X1 * ImageData1[i].Z2 - ImageData1[i].X2 * ImageData1[i].Z1);
N21[i] = (bx * ImageData1[i].Z1 - bz1 * ImageData1[i].X1) / (ImageData1[i].X1 * ImageData1[i].Z2 - ImageData1[i].X2 * ImageData1[i].Z1);
//计算线性化矩阵A(系数)
A1[i][0] = bx;
A1[i][1] = -(ImageData1[i].Y2 / ImageData1[i].Z2) * bx;
A1[i][2] = -(ImageData1[i].X2 * ImageData1[i].Y2 * N21[i]) / ImageData1[i].Z2;
A1[i][3] = -(ImageData1[i].Z2 + (ImageData1[i].Y2 * ImageData1[i].Y2) / ImageData1[i].Z2) * N21[i];
A1[i][4] = ImageData1[i].X2 * N21[i];
//计算上下视差矩阵Q
Q1[i] = N11[i] * ImageData1[i].Y1 - N21[i] * ImageData1[i].Y2 - by1;
}
//构建误差方程及法方程,最小二乘法求相对定向元素
//计算转置矩阵
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 5; j++)
{
R11[j][i] = A1[i][j];
}
}
matrix_multiply(&R11[0][0],5,15,&A1[0][0],15,5, &B1[0][0]);//得到B
InverseMatrix(&B1[0][0],5, &BB1[0][0]);
//计算(ATA)-1AT
for (int i = 0; i < 5; i++)
{
for (int m = 0; m < 15; m++)
{
A11[i][m] = 0;
for (int j = 0; j < 5; j++)
{
A11[i][m] += BB1[i][j] * R11[j][m];
}
}
}
for (int i = 0; i < 5; i++)
{
result1[i] = 0;
for (int j = 0; j < 15; j++)
{
result1[i] += A11[i][j] * Q1[j];
}
}//得到改正数
if (fabs(result1[0]) < 0.000001 && fabs(result1[1]) < 0.000001 && fabs(result1[2]) < 0.000001 && fabs(result1[3]) < 0.000001 && fabs(result1[4]) < 0.000001)
{
φ21 += result1[2];
ω21 += result1[3];
κ21 += result1[4];
a1 = cos(φ21) * cos(κ21) - sin(φ21) * sin(ω21) * sin(κ21),
a2 = -cos(φ21) * sin(κ21) - sin(φ21) * sin(ω21) * cos(κ21),
a3 = -sin(φ21) * cos(ω21),
b1 = cos(ω21) * sin(κ21),
b2 = cos(ω21) * cos(κ21),
b3 = -sin(ω21),
c1 = sin(φ21) * cos(κ21) + cos(ω21) * sin(ω21) * sin(κ21),
c2 = -sin(φ21) * sin(κ21) + cos(ω21) * sin(ω21) * cos(κ21),
c3 = cos(φ21) * cos(ω21);
a4 = a1;
a5 = a2;
a6 = a3;
b4 = b1;
b5 = b2;
b6 = b3;
c4 = c1;
c5 = c2;
c6 = c3;
break;
}
}
printf("\n第一个像对的相对定向结果\n");
printf("μ=%lf γ=%1f φ2=%1f ω2=%1f κ2=%1f by=%1f bz=%1f 循环次数=%d", μ1, γ1, φ21, ω21, κ21, by1, bz1, i1);
#pragma endregion
#pragma region 第二个像对的相对定向
for (i2 = 1;; i2++)//第二个文件相对定向元素
{
//初始化相对定向元素
μ2 += result2[0];
γ2 += result2[1];
φ22 += result2[2];
ω22 += result2[3];
κ22 += result2[4];
by2 = bx * μ2;
bz2 = bx * γ2;
//旋转矩阵的方向元素
double
a1 = cos(φ22) * cos(κ22) - sin(φ22) * sin(ω22) * sin(κ22),
a2 = -cos(φ22) * sin(κ22) - sin(φ22) * sin(ω22) * cos(κ22),
a3 = -sin(φ22) * cos(ω22),
b1 = cos(ω22) * sin(κ22),
b2 = cos(ω22) * cos(κ22),
b3 = -sin(ω22),
c1 = sin(φ22) * cos(κ22) + cos(ω22) * sin(ω22) * sin(κ22),
c2 = -sin(φ22) * sin(κ22) + cos(ω22) * sin(ω22) * cos(κ22),
c3 = cos(φ22) * cos(ω22);
for (int i = 0; i < 8; i++)
{
//像点的像空辅坐标系
ImageData2[i].index = ImageData[i+15].index;
ImageData2[i].X1 = a4 * ImageData[i + 15].x1 + a5 * ImageData[i + 15].y1 + a6 * (-f);
ImageData2[i].Y1 = b4 * ImageData[i + 15].x1 + b5 * ImageData[i + 15].y1 + b6 * (-f);
ImageData2[i].Z1 = c4 * ImageData[i + 15].x1 + c5 * ImageData[i + 15].y1 + c6 * (-f);
ImageData2[i].X2 = a1 * ImageData[i + 15].x2 + a2 * ImageData[i + 15].y2 + a3 * (-f);//R2
ImageData2[i].Y2 = b1 * ImageData[i + 15].x2 + b2 * ImageData[i + 15].y2 + b3 * (-f);
ImageData2[i].Z2 = c1 * ImageData[i + 15].x2 + c2 * ImageData[i + 15].y2 + c3 * (-f);
//计算投影系数
N12[i] = (bx * ImageData2[i].Z2 - bz2 * ImageData2[i].X2) / (ImageData2[i].X1 * ImageData2[i].Z2 - ImageData2[i].X2 * ImageData2[i].Z1);
N22[i] = (bx * ImageData2[i].Z1 - bz2 * ImageData2[i].X1) / (ImageData2[i].X1 * ImageData2[i].Z2 - ImageData2[i].X2 * ImageData2[i].Z1);
//计算线性化矩阵A(系数)
A2[i][0] = bx;
A2[i][1] = -(ImageData2[i].Y2 / ImageData2[i].Z2) * bx;
A2[i][2] = -(ImageData2[i].X2 * ImageData2[i].Y2 * N22[i]) / ImageData2[i].Z2;
A2[i][3] = -(ImageData2[i].Z2 + (ImageData2[i].Y2 * ImageData2[i].Y2) / ImageData2[i].Z2) * N22[i];
A2[i][4] = ImageData2[i].X2 * N22[i];
//计算上下视差矩阵Q
Q2[i] = N12[i] * ImageData2[i].Y1 - N22[i] * ImageData2[i].Y2 - by2;
}
//构建误差方程及法方程,最小二乘法求相对定向元素
//计算转置矩阵
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 5; j++)
{
R12[j][i] = A2[i][j];
}
}
matrix_multiply(&R12[0][0], 5, 8, &A2[0][0], 8, 5, &B2[0][0]);//得到B
InverseMatrix(&B2[0][0], 5, &BB2[0][0]);
//计算(ATA)-1AT
for (int i = 0; i < 5; i++)
{
for (int m = 0; m < 8; m++)
{
A12[i][m] = 0;
for (int j = 0; j < 5; j++)
{
A12[i][m] += BB2[i][j] * R12[j][m];
}
}
}
for (int i = 0; i < 5; i++)
{
result2[i] = 0;
for (int j = 0; j < 8; j++)
{
result2[i] += A12[i][j] * Q2[j];
}
}//得到改正数
if (fabs(result2[0]) < 0.000001 && fabs(result2[1]) < 0.000001 && fabs(result2[2]) < 0.000001 && fabs(result2[3]) < 0.000001 && fabs(result2[4]) < 0.000001)
{
φ22 += result2[2];
ω22 += result2[3];
κ22 += result2[4];
a1 = cos(φ22) * cos(κ22) - sin(φ22) * sin(ω22) * sin(κ22),
a2 = -cos(φ22) * sin(κ22) - sin(φ22) * sin(ω22) * cos(κ22),
a3 = -sin(φ22) * cos(ω22),
b1 = cos(ω22) * sin(κ22),
b2 = cos(ω22) * cos(κ22),
b3 = -sin(ω22),
c1 = sin(φ22) * cos(κ22) + cos(ω22) * sin(ω22) * sin(κ22),
c2 = -sin(φ22) * sin(κ22) + cos(ω22) * sin(ω22) * cos(κ22),
c3 = cos(φ22) * cos(ω22);
a4 = a1;
a5 = a2;
a6 = a3;
b4 = b1;
b5 = b2;
b6 = b3;
c4 = c1;
c5 = c2;
c6 = c3;
break;
}
}
printf("\n第二个像对的相对定向结果\n");
printf("μ=%lf γ=%1f φ2=%1f ω2=%1f κ2=%1f by=%1f bz=%1f 循环次数=%d", μ2, γ2, φ22, ω22, κ22, by2, bz2, i2);
#pragma endregion
#pragma region 第三个像对的相对定向
for (i3 = 1;; i3++)//第三个文件相对定向元素
{
//初始化相对定向元素
μ3 += result3[0];
γ3 += result3[1];
φ23 += result3[2];
ω23 += result3[3];
κ23 += result3[4];
by3 = bx * μ3;
bz3 = bx * γ3;
//旋转矩阵的方向元素
double
a1 = cos(φ23) * cos(κ23) - sin(φ23) * sin(ω23) * sin(κ23),
a2 = -cos(φ23) * sin(κ23) - sin(φ23) * sin(ω23) * cos(κ23),
a3 = -sin(φ23) * cos(ω23),
b1 = cos(ω23) * sin(κ23),
b2 = cos(ω23) * cos(κ23),
b3 = -sin(ω23),
c1 = sin(φ23) * cos(κ23) + cos(ω23) * sin(ω23) * sin(κ23),
c2 = -sin(φ23) * sin(κ23) + cos(ω23) * sin(ω23) * cos(κ23),
c3 = cos(φ23) * cos(ω23);
for (int i = 0; i < 11; i++)
{
//像点的像空间辅助坐标系
ImageData3[i].index = ImageData[i + 23].index;
ImageData3[i].X1 = a4 * ImageData[i + 23].x1 + a5 * ImageData[i + 23].y1 + a6 * (-f);
ImageData3[i].Y1 = b4 * ImageData[i + 23].x1 + b5 * ImageData[i + 23].y1 + b6 * (-f);
ImageData3[i].Z1 = c4 * ImageData[i + 23].x1 + c5 * ImageData[i + 23].y1 + c6 * (-f);
ImageData3[i].X2 = a1 * ImageData[i + 23].x2 + a2 * ImageData[i + 23].y2 + a3 * (-f);//R2
ImageData3[i].Y2 = b1 * ImageData[i + 23].x2 + b2 * ImageData[i + 23].y2 + b3 * (-f);
ImageData3[i].Z2 = c1 * ImageData[i + 23].x2 + c2 * ImageData[i + 23].y2 + c3 * (-f);
//计算投影系数
N13[i] = (bx * ImageData3[i].Z2 - bz3 * ImageData3[i].X2) / (ImageData3[i].X1 * ImageData3[i].Z2 - ImageData3[i].X2 * ImageData3[i].Z1);
N23[i] = (bx * ImageData3[i].Z1 - bz3 * ImageData3[i].X1) / (ImageData3[i].X1 * ImageData3[i].Z2 - ImageData3[i].X2 * ImageData3[i].Z1);
//计算线性化矩阵A(系数)
A3[i][0] = bx;
A3[i][1] = -(ImageData3[i].Y2 / ImageData3[i].Z2) * bx;
A3[i][2] = -(ImageData3[i].X2 * ImageData3[i].Y2 * N23[i]) / ImageData3[i].Z2;
A3[i][3] = -(ImageData3[i].Z2 + (ImageData3[i].Y2 * ImageData3[i].Y2) / ImageData3[i].Z2) * N23[i];
A3[i][4] = ImageData3[i].X2 * N23[i];
//计算上下视差矩阵Q
Q3[i] = N13[i] * ImageData3[i].Y1 - N23[i] * ImageData3[i].Y2 - by3;
}
//构建误差方程及法方程,最小二乘法求相对定向元素
//计算转置矩阵
for (int i = 0; i < 11; i++)
{
for (int j = 0; j < 5; j++)
{
R13[j][i] = A3[i][j];
}
}
matrix_multiply(&R13[0][0], 5, 11, &A3[0][0], 11, 5, &B3[0][0]);//得到B
InverseMatrix(&B3[0][0], 5, &BB3[0][0]);
//计算(ATA)-1AT
for (int i = 0; i < 5; i++)
{
for (int m = 0; m < 11; m++)
{
A13[i][m] = 0;
for (int j = 0; j < 5; j++)
{
A13[i][m] += BB3[i][j] * R13[j][m];
}
}
}
for (int i = 0; i < 5; i++)
{
result3[i] = 0;
for (int j = 0; j < 11; j++)
{
result3[i] += A13[i][j] * Q3[j];
}
}//得到改正数
if (fabs(result3[0]) < 0.000001 && fabs(result3[1]) < 0.000001 && fabs(result3[2]) < 0.000001 && fabs(result3[3]) < 0.000001 && fabs(result3[4]) < 0.000001)
{
φ23 += result3[2];
ω23 += result3[3];
κ23 += result3[4];
break;
}
}
printf("\n第三个像对的相对定向结果\n");
printf("μ=%lf γ=%1f φ2=%1f ω2=%1f κ2=%1f by=%1f bz=%1f 循环次数=%d", μ3, γ3, φ23, ω23, κ23, by3, bz3, i3);
#pragma endregion
#pragma region 求比例尺m
double distance1[3], distance2[3];
distance1[0] = sqrt((ImageData[0].x1 - ImageData[5].x1) * (ImageData[0].x1 - ImageData[5].x1) + (ImageData[0].y1 - ImageData[5].y1) * (ImageData[0].y1 - ImageData[5].y1));
distance1[1] = sqrt((ImageData[0].x1 - ImageData[6].x1) * (ImageData[0].x1 - ImageData[6].x1) + (ImageData[0].y1 - ImageData[6].y1) * (ImageData[0].y1 - ImageData[6].y1));
distance1[2] = sqrt((ImageData[5].x1 - ImageData[6].x1) * (ImageData[5].x1 - ImageData[6].x1) + (ImageData[5].y1 - ImageData[6].y1) * (ImageData[5].y1 - ImageData[6].y1));
distance2[0] = sqrt((ControlData[0].X - ControlData[1].X) * (ControlData[0].X - ControlData[1].X) + (ControlData[0].Y - ControlData[1].Y) * (ControlData[0].Y - ControlData[1].Y));
distance2[1] = sqrt((ControlData[0].X - ControlData[2].X) * (ControlData[0].X - ControlData[2].X) + (ControlData[0].Y - ControlData[2].Y) * (ControlData[0].Y - ControlData[2].Y));
distance2[2] = sqrt((ControlData[2].X - ControlData[1].X) * (ControlData[2].X - ControlData[1].X) + (ControlData[2].Y - ControlData[1].Y) * (ControlData[2].Y - ControlData[1].Y));
double M[3], m;
M[0] = distance2[0] / distance1[1];
M[1] = distance2[1] / distance1[1];
M[2] = distance2[2] / distance1[2];
m = (M[0] + M[1] + M[2]) / 3;
printf("\n");
printf("比例尺:m=%lf ", m);
#pragma endregion
#pragma region 航带网模型的建立
//上述已求得像点的像空间辅助坐标系
// 此时各模型的像空间辅助坐标系坐标轴向都保持平行
//但模型比,例尺各不相同,坐标原点也不一致
data5 ModelspaceAid1[15];//模型点的像空间辅助坐标系
data5 ModelspaceAid2[8];
data5 ModelspaceAid3[11];
for (int i = 0; i < 15; i++)
{
ModelspaceAid1[i].index = ImageData1[i].index;
ModelspaceAid1[i].X1 = ImageData1[i].X1 * N11[i];
ModelspaceAid1[i].Y1 = (ImageData1[i].Y1 * N11[i] + ImageData1[i].Y2 * N21[i] + by1) / 2;
ModelspaceAid1[i].Z1 = ImageData1[i].Z1 * N11[i];
}
for (int i = 0; i < 8; i++)
{
ModelspaceAid2[i].index = ImageData2[i].index;
ModelspaceAid2[i].X1 = ImageData2[i].X1 * N12[i];
ModelspaceAid2[i].Y1 = (ImageData2[i].Y1 * N12[i] + ImageData2[i].Y2 * N22[i] + by2) / 2;
ModelspaceAid2[i].Z1 = ImageData2[i].Z1 * N12[i];
}
for (int i = 0; i < 11; i++)
{
ModelspaceAid3[i].index = ImageData3[i].index;
ModelspaceAid3[i].X1 = ImageData3[i].X1 * N13[i];
ModelspaceAid3[i].Y1 = (ImageData3[i].Y1 * N13[i] + ImageData3[i].Y2 * N23[i] + by3) / 2;
ModelspaceAid3[i].Z1 = ImageData3[i].Z1 * N13[i];
}
//航带内各立体模型利用公共点进行连接,建立起统一的航带网模型。
//若要将航带内所有模型连接构成航带网,必须要进行各模型之间比例尺的归算,即K1,K2
double K1[3] = { 0 }, K2[3] = { 0 };
int count1 = 0, count2 = 0;
double k1 = 0, k2 = 0;
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 8; j++)
{
if (ModelspaceAid1[i].index == ModelspaceAid2[j].index && count1 < 3)
{
K1[count1] = (ModelspaceAid1[i].Z1 - bz1) / (ModelspaceAid2[j].Z1);
k1 += K1[count1];
count1++;
}
}
}
k1 = k1 / 3;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 11; j++)
{
if (ModelspaceAid2[i].index == ModelspaceAid3[j].index && count2 < 3)
{
K2[count2] = (ModelspaceAid2[i].Z1 - bz2) / (ModelspaceAid3[j].Z1);
k2 += K2[count2];
count2++;
}
}
}
k2 = k2 / 3;
printf("\n");
printf("各模型之间的比例尺的归算:k1 = %1f k2 = %1f ", k1, k2);
printf("\n");
//航带内各单个模型建立以后,以相邻两模型重叠范围内三个连接点的高度应相等为条件,
// 沿航带从左至右,逐个模型的归化比例尺,统一坐标原点,
// 使全航带各模型连接成一个统一的自由航带网模型,将模型点的坐标换算到摄影测量坐标系中
//此时需要使用K1、K2,继续计算模型点摄影测量坐标
double Xps[4], Yps[4], Zps[4];
Xps[0] = 0;
Yps[0] = 0;
Zps[0] = m * f;
Xps[1] = Xps[0] + m * bx;
Yps[1] = Yps[0] + m * by1;
Zps[1] = Zps[0] + m * bz1;
Xps[2] = Xps[1] + k1 * m * bx;
Yps[2] = Yps[1] + k1 * m * by2;
Zps[2] = Zps[1] + k1 * m * bz2;
Xps[3] = Xps[2] + k1 * k2 * m * bx;
Yps[3] = Yps[2] + k1 * k2 * m * by3;
Zps[3] = Zps[2] + k1 * k2 * m * bz3;
//计算最终的模型点坐标(摄影测量坐标系)
data5 Photography1[15];
data5 Photography2[8];
data5 Photography3[11];
for (int i = 0; i < 15; i++)
{
Photography1[i].index = ModelspaceAid1[i].index;
Photography1[i].X1 = ModelspaceAid1[i].X1 * m;
Photography1[i].Y1 = ModelspaceAid1[i].Y1 * m;
Photography1[i].Z1 = Zps[0] + ModelspaceAid1[i].Z1 * m;
}
for (int i = 0; i < 8; i++)
{
Photography2[i].index = ModelspaceAid2[i].index;
Photography2[i].X1 = Xps[1] + k1 * ModelspaceAid2[i].X1 * m;
Photography2[i].Y1 = (Yps[1] + k1 * m * N12[i] * ImageData2[i].Y1 + Yps[2] + k1 * m * N22[i] * ImageData2[i].Y2) / 2;//公式有点问题???
Photography2[i].Z1 = Zps[1] + k1 * ModelspaceAid2[i].Z1 * m;
}
for (int i = 0; i < 11; i++)
{
Photography3[i].index = ModelspaceAid3[i].index;
Photography3[i].X1 = Xps[2] + k1 * k2 * ModelspaceAid3[i].X1 * m;
Photography3[i].Y1 = (Yps[2] + k1 * k2 * m * N13[i] * ImageData3[i].Y1 + Yps[3] + k1 * k2 * m * N23[i] * ImageData3[i].Y2 ) / 2;
Photography3[i].Z1 = Zps[2] + k1 * k2 * ModelspaceAid3[i].Z1 * m;
}
#pragma endregion
#pragma region 绝对定向求解七参数
//在航带网的两端,分别选定1和2两个控制点,根据这两点的地面测量坐标和摄影测量坐标,
// 将测区内所有地面控制点的地面测量坐标和对应的摄影测量坐标都换算为以1点为坐标原点的坐标。
// 同时,将自由航带网内所有加密点的摄影测量坐标也换算为以1点为原点的坐标。
// 求dx dy
double dXt, dYt, dXp, dYp;
dXt = ControlData[0].X - ControlData[3].X;//控制点的大地坐标差
dYt = ControlData[0].Y - ControlData[3].Y;
dXp = Photography1[0].X1 - Photography3[8].X1;//摄影测量坐标差
dYp = Photography1[0].Y1 - Photography3[8].Y1;
//计算转换系数a b T
double a, b, T;
a = (dXp * dYt + dYp * dXt) / (dXt * dXt + dYt * dYt);
b = (dXp * dXt - dYp * dYt) / (dXt * dXt + dYt * dYt);
T = sqrt(a * a + b * b);
printf("\n");
printf("三个转换系数:%lf %lf %lf ", a, b, T);
//求得三参数后,将所有地面控制点的大地坐标系计算变换成的地面摄影测量坐标Xtp
data3 controlXt_to_Xtp[4];
for (int i = 0; i < 4; i++)
{
controlXt_to_Xtp[i].X = b * (ControlData[i].X - ControlData[0].X) + (ControlData[i].Y - ControlData[0].Y) * a;
controlXt_to_Xtp[i].Y = a * (ControlData[i].X - ControlData[0].X) + (ControlData[i].Y - ControlData[0].Y) * (-b);
controlXt_to_Xtp[i].Z = T * (ControlData[i].Z - ControlData[0].Z);
}
//摄影测量坐标Xp
data4 Photography1_controlXp[10] = { 0 };//与控制点对应的模型点摄影测量坐标
int point4 = 0;
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 4; j++)
{
if (Photography1[i].index == ControlData[j].index)
{
Photography1_controlXp[point4].index = Photography1[i].index;
Photography1_controlXp[point4].x = Photography1[i].X1;
Photography1_controlXp[point4].y = Photography1[i].Y1;
Photography1_controlXp[point4].z = Photography1[i].Z1;
point4++;
}
}
}
data4 Photography3_controlXp[10] = { 0 };
int point5 = 0;
for (int i = 0; i < 11; i++)
{
for (int j = 0; j < 4; j++)
{
if (Photography3[i].index == ControlData[j].index)
{
Photography3_controlXp[point5].index = Photography3[i].index;
Photography3_controlXp[point5].x = Photography3[i].X1;
Photography3_controlXp[point5].y = Photography3[i].Y1;
Photography3_controlXp[point5].z = Photography3[i].Z1;
point5++;
}
}
}
//计算地面摄影测量坐标和摄影测量坐标
data3 tp[4], p[4];
for (int i = 0; i < 4; i++)
{
tp[i].X = controlXt_to_Xtp[i].X;
tp[i].Y = controlXt_to_Xtp[i].Y;
tp[i].Z = controlXt_to_Xtp[i].Z;
}
for (int i = 0; i < 3; i++)
{
p[i].X = Photography1_controlXp[i].x;
p[i].Y = Photography1_controlXp[i].y;
p[i].Z = Photography1_controlXp[i].z;
}
p[3].X = Photography3_controlXp[0].x;
p[3].Y = Photography3_controlXp[0].y;
p[3].Z = Photography3_controlXp[0].z;
//printf("\n------------------------\n");
//for (int i = 0; i < 4; i++)
//{
// printf("%lf ", controlXt_to_Xtp[i].X);
//}
//计算绝对定向元素
double T0 = 1, X0 = 0, Y0 = 0, Z0 = 0, φ = 0, ω = 0, κ = 0;//七参数
double result4[7] = { 0 };//改正数
double L[12] = { 0 };//4个控制点,Lx,Ly,Lz有三个常数项
//误差方程与法方程
double A[12][7] = { 0 };
double AT[7][12];
double ATA[7][7];
double ATA1[7][7];
double AA[7][12];
for (int i5 = 1;; i5++)
{
//printf("%d ", i5);
//初始化
X0 += result4[0];
Y0 += result4[1];
Z0 += result4[2];
T0 += result4[3];
φ += result4[4];
ω += result4[5];
κ += result4[6];
double
a1 = cos(φ) * cos(κ) - sin(φ) * sin(ω) * sin(κ),
a2 = -cos(φ) * sin(κ) - sin(φ) * sin(ω) * cos(κ),
a3 = -sin(φ) * cos(ω),
b1 = cos(ω) * sin(κ),
b2 = cos(ω) * cos(κ),
b3 = -sin(ω),
c1 = sin(φ) * cos(κ) + cos(ω) * sin(ω) * sin(κ),
c2 = -sin(φ) * sin(κ) + cos(ω) * sin(ω) * cos(κ),
c3 = cos(φ) * cos(ω);
for (int i = 0; i < 4; i++)
{
int j = i * 3;
L[j] = tp[i].X - T0 * (a1 * p[i].X + a2 * p[i].Y + a3 * p[i].Z) - X0;
L[j + 1] = tp[i].Y - T0 * (b1 * p[i].X + b2 * p[i].Y + b3 * p[i].Z) - Y0;
L[j + 2] = tp[i].Z - T0 * (c1 * p[i].X + c2 * p[i].Y + c3 * p[i].Z) - Z0;
}
//计算A矩阵
// 计算A矩阵
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 7; j++) {
int idx = i / 3; // p数组的索引
// 处理对角线元素
if (i % 3 == j) {
A[i][j] = 1;
}
// 处理特定列的赋值
else if ((i == 0 || i == 3 || i == 6 || i == 9) && j == 3) {
A[i][j] = p[idx].X;
}
else if ((i == 2 || i == 5 || i == 8 || i == 11) && j == 4) {
A[i][j] = p[idx].X;
}
else if ((i == 1 || i == 4 || i == 7 || i == 10) && j == 6) {
A[i][j] = p[idx].X;
}
else if ((i == 1 || i == 4 || i == 7 || i == 10) && j == 3) {
A[i][j] = p[idx].Y;
}
else if ((i == 2 || i == 5 || i == 8 || i == 11) && j == 5) {
A[i][j] = p[idx].Y;
}
else if ((i == 0 || i == 3 || i == 6 || i == 9) && j == 6) {
A[i][j] = -p[idx].Y;
}
else if ((i == 2 || i == 5 || i == 8 || i == 11) && j == 3) {
A[i][j] = p[idx].Z;
}
else if ((i == 1 || i == 4 || i == 7 || i == 10) && j == 5) {
A[i][j] = -p[idx].Z;
}
else if ((i == 0 || i == 3 || i == 6 || i == 9) && j == 4) {
A[i][j] = -p[idx].Z;
}
}
}
//计算A的转置
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 7; j++)
{
AT[j][i] = A[i][j];
}
}
for (int i = 0; i < 7; i++)
{
for (int m = 0; m < 7; m++)
{
ATA[i][m] = 0;
for (int j = 0; j < 12; j++)
{
ATA[i][m] += AT[i][j] * A[j][m];
}
}
}
//求逆
InverseMatrix(&ATA[0][0], 7, &ATA1[0][0]);
//计算(ATA)-1AT
for (int i = 0; i < 7; i++)
{
for (int m = 0; m < 12; m++)
{
AA[i][m] = 0;
for (int j = 0; j < 7; j++)
{
AA[i][m] += ATA1[i][j] * AT[j][m];
}
}
}
//计算最终结果
for (int i = 0; i < 7; i++)
{
result4[i] = 0;
for (int j = 0; j < 12; j++)
{
result4[i] += AA[i][j] * L[j];
}
}
if (fabs(result4[0]) < 0.0000001 && fabs(result4[1]) < 0.0000001 && fabs(result4[5]) < 0.0000001 && fabs(result4[2]) < 0.0000001 && fabs(result4[3]) < 0.0000001 && fabs(result4[4]) < 0.0000001 && fabs(result4[6]) < 0.0000001)
{
printf("\n");
printf("绝对定向结束");
break;
}
}
printf("\n");
printf("%lf %lf %lf %lf %lf %lf %lf ", X0, Y0, Z0, T0, φ, ω, κ);
#pragma endregion
#pragma region 绝对定向摄影转地面摄影
// 计算三个模型的摄影测量坐标——>地面摄影测量坐标
data3 modeltp1[15], modeltp2[8], modeltp3[11];
for (int i = 0; i < 15; i++)
{
modeltp1[i].index = Photography1[i].index;
modeltp1[i].X = T0 * (Photography1[i].X1 - κ * Photography1[i].Y1 - φ * Photography1[i].Z1) + X0;
modeltp1[i].Y = T0 * (κ * Photography1[i].X1 + Photography1[i].Y1 - ω * Photography1[i].Z1) + Y0;
modeltp1[i].Z = T0 * (φ * Photography1[i].X1 + ω * Photography1[i].Y1 + Photography1[i].Z1) + Z0;
}
for (int i = 0; i < 8; i++)
{
modeltp2[i].index = Photography2[i].index;
modeltp2[i].X = T0 * (Photography2[i].X1 - κ * Photography2[i].Y1 - φ * Photography2[i].Z1) + X0;
modeltp2[i].Y = T0 * (κ * Photography2[i].X1 + Photography2[i].Y1 - ω * Photography2[i].Z1) + Y0;
modeltp2[i].Z = T0 * (φ * Photography2[i].X1 + ω * Photography2[i].Y1 + Photography2[i].Z1) + Z0;
}
for (int i = 0; i < 11; i++)
{
modeltp3[i].index = Photography3[i].index;
modeltp3[i].X = T0 * (Photography3[i].X1 - κ * Photography3[i].Y1 - φ * Photography3[i].Z1) + X0;
modeltp3[i].Y = T0 * (κ * Photography3[i].X1 + Photography3[i].Y1 - ω * Photography3[i].Z1) + Y0;
modeltp3[i].Z = T0 * (φ * Photography3[i].X1 + ω * Photography3[i].Y1 + Photography3[i].Z1) + Z0;
}
//计算最终的大地坐标
data3 finish1[15], finish2[8], finish3[11];
for (int i = 0; i < 15; i++)
{
finish1[i].index = modeltp1[i].index;
finish1[i].X = (b * modeltp1[i].X + a * modeltp1[i].Y) / T / T + ControlData[0].X;
finish1[i].Y = (a * modeltp1[i].X - b * modeltp1[i].Y) / T / T + ControlData[0].Y;
finish1[i].Z = (modeltp1[i].Z) / T + ControlData[0].Z;
}
printf("\n---------------------------\n");
for (int i = 0; i < 15; i++)
{
printf("%lf ", finish1[i].X);
}
for (int i = 0; i < 8; i++)
{
finish2[i].index = modeltp2[i].index;
finish2[i].X = (b * modeltp2[i].X + a * modeltp2[i].Y) / T / T + ControlData[0].X;
finish2[i].Y = (a * modeltp2[i].X - b * modeltp2[i].Y) / T / T + ControlData[0].Y;
finish2[i].Z = (modeltp2[i].Z) / T + ControlData[0].Z;
}
for (int i = 0; i < 11; i++)
{
finish3[i].index = modeltp3[i].index;
finish3[i].X = (b * modeltp3[i].X + a * modeltp3[i].Y) / T / T + ControlData[0].X;
finish3[i].Y = (a * modeltp3[i].X - b * modeltp3[i].Y) / T / T + ControlData[0].Y;
finish3[i].Z = (modeltp3[i].Z) / T + ControlData[0].Z;
}
//检查点 计算差值
double D[5][4] = { 0 };
for (i = 0; i < 5; i++)
{
for (int j = 0; j < 15; j++)
{
if (CheckData[i].index == finish1[j].index)
{
D[i][0] = CheckData[i].index;
D[i][1] = CheckData[i].X_ - finish1[j].X;
D[i][2] = CheckData[i].Y_ - finish1[j].Y;
D[i][3] = CheckData[i].Z_ - finish1[j].Z;
break;
}
}
for (int j = 0; j < 8; j++)
{
if (CheckData[i].index == finish2[j].index)
{
D[i][0] = CheckData[i].index;
D[i][1] = CheckData[i].X_ - finish2[j].X;
D[i][2] = CheckData[i].Y_ - finish2[j].Y;
D[i][3] = CheckData[i].Z_ - finish2[j].Z;
break;
}
}
for (int j = 0; j < 11; j++)
{
if (CheckData[i].index == finish3[j].index)
{
D[i][0] = CheckData[i].index;
D[i][1] = CheckData[i].X_ - finish3[j].X;
D[i][2] = CheckData[i].Y_ - finish3[j].Y;
D[i][3] = CheckData[i].Z_ - finish3[j].Z;
break;
}
}
}
#pragma endregion
#pragma region 写入文件
//写入文件
FILE* fp2;
fp2 = fopen("result.txt", "w");
fprintf(fp2, "****************相对定向元素*******************\n");
fprintf(fp2, "\n");
fprintf(fp2, " 三个像对最终的相对定向元素结果:\n ");
fprintf(fp2, "\n");
fprintf(fp2, "μ γ φ ω κ by bz 循环次数\n");
fprintf(fp2, "第一个像对:\n");
fprintf(fp2, " %10.8f %f %f %f %f %f %f %d\n", μ1, γ1, φ21, ω21, κ21, by1, bz1, i1);
fprintf(fp2, "\n");
fprintf(fp2, "第一个像对:\n");
fprintf(fp2, " %10.8f %f %f %f %f %f %f %d\n", μ2, γ2, φ22, ω22, κ22, by2, bz2, i2);
fprintf(fp2, "\n");
fprintf(fp2, "第一个像对:\n");
fprintf(fp2, " %10.8f %f %f %f %f %f %f %d\n", μ3, γ3, φ23, ω23, κ23, by3, bz3, i3);
fprintf(fp2, "\n");
fprintf(fp2, "****************航带网的建立*******************\n");
fprintf(fp2, "\n");
fprintf(fp2, "比例尺m = %f \n", m);
fprintf(fp2, "\n");
fprintf(fp2, "比例尺缩放系数: k1 = %f k2 = %f \n", k1, k2);
fprintf(fp2, "\n");
fprintf(fp2, "三个转换系数: a = %f b = %f T = %f\n", a, b, T);
fprintf(fp2, "\n绝对定向元素 \n");
fprintf(fp2, " T0 = %f X0 = %f Y0 = %f Z0 = %f φ = %f ω = %f κ = %f \n", T0, X0, Y0, Z0, φ, ω, κ);
fprintf(fp2, "\n");
fprintf(fp2, "****************模型连接*******************\n");
fprintf(fp2, "\n 最后的大地坐标 \n");
for (int i = 0; i < 15; i++)
{
fprintf(fp2, " %f %f %f \n", finish1[i].X, finish1[i].Y, finish1[i].Z);
}
fprintf(fp2, "\n");
for (int i = 0; i < 8; i++)
{
fprintf(fp2, " %f %f %f\n ", finish2[i].X, finish2[i].Y, finish2[i].Z);
}
fprintf(fp2, "\n");
for (int i = 0; i < 11; i++)
{
fprintf(fp2, " %f %f %f \n", finish3[i].X, finish3[i].Y, finish3[i].Z);
}
fprintf(fp2, "\n 与待定点的差值 \n");
for (int j = 0; j < 5; j++)
{
fprintf(fp2, " %f %f %f \n", D[j][1], D[j][2], D[j][3]);
}
fprintf(fp2, "\n");
fclose(fp2);
//写入文件结束
#pragma endregion
return 0;
}
注意:上述代码可以直接运行,只需要将数据导入CSV表格即可,格式如下:
最终结果:
附:其他版本的像点数据之间可能不一样,今年版本的数据稍有改动,但是不知道为什么检查点的误差在Z轴上这么大。