MATLAB--导线测量

2024-02-06 08:20
文章标签 matlab 测量 导线

本文主要是介绍MATLAB--导线测量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

MATLAB–导线测量

一.前言

在本文中,我将重点介绍如何利用MATLAB进行导线测量的计算。函数实现皆为自己所写,我也是初学者,对着流程一步步实现的,仅供学习。为了使导线测量更加用户友好,我尝试使用MATLAB的GUI工具来简化测量过程并提供更直观的结果展示。通过GUI界面,用户可以方便地输入坐标点、选择测量功能、查看测量结果等。

导线测量是工程领域中的一项非常重要的技术,在测绘、建筑、电力等各个领域都有广泛的应用。本文将重点介绍一种基于MATLAB的导线测量方法,并逐步讲解实现过程,帮助初学者更好地理解和应用该方法。如果读者在本文中遇到了困难,可以参考我主页上传的资源,获取更多的帮助和支持。

在本文中,我将通过实例来介绍导线测量方法的具体实现。我将逐步介绍如何编写MATLAB程序,实现导线测量的各个步骤。我会提供充足的代码示例和注释,以帮助读者更好地理解和理解方法的核心原理。

二.程序展示

首先先看下程序的整体效果:

运行后的改正坐标增量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后结果就是最后一列空白,比起手算还是很方便的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还有右方的内存区域:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里博主为了省事,将需要的变量定义为了拼音缩写,比如zbzl为坐标增量的意思嘻嘻嘻。

三.代码解析

先提前解释下我所写的角之间计算的函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

function result = calJiaojia(a,b)%计算角之间相加的函数if isnumeric(a) && isscalar(a)a=[a,0,0];endif isnumeric(b) && isscalar(b)b=[b,0,0];endjinwei=0;miao=a(3)+b(3);jinwei=fix(miao/60);if (miao>=60)miao=mod(miao,60);endfen=a(2)+b(2)+jinwei;jinwei=fix(fen/60);if (fen>=60)fen=mod(fen,60);enddu=a(1)+b(1)+jinwei;result=[du,fen,miao];

细看就是正常的加法运算,它接受两个角度(用度、分、秒表示)作为参数,并返回它们相加的结果(也用度、分、秒表示)。

首先,将输入的角度 a 和 b 转换为标准格式:一个三元素的数组,分别表示角度的度数、分数和秒数。如果输入的角度不是标量或不是数字,会将其转换为度数为输入值,分数和秒数为 0 的标准格式。

然后,将两个角度的秒数之和计算出来,并检查是否超过了 60。如果超过了,需要将超出的部分进行进位加到分数上,并更新秒数为余数部分。

接着,将两个角度的分数之和计算出来,并检查是否超过了 60。如果超过了,需要将超出的部分进行进位加到度数上,并更新分数为余数部分。

最后,将两个角度的度数之和计算出来,并将度数、分数和秒数作为三个元素构成的数组返回作为函数的结果。

这个函数用于计算角度的数值相加,方便在需要进行角度加法运算的场景中使用。

同理减法运算:

function result = calJiaojian(a,b)if isnumeric(a) && isscalar(a)a=[a,0,0];endif isnumeric(b) && isscalar(b)b=[b,0,0];endtempz=a(1)-b(1);if tempz>=0temp=a(3)-b(3);if temp<0a(2)=a(2)-1;a(3)=a(3)+60;miao=a(3)-b(3);elsemiao=temp;endtemp=a(2)-b(2);if temp<0a(1)=a(1)-1;a(2)=a(2)+60;fen=a(2)-b(2);elsefen=temp;enddu=a(1)-b(1);result=[du,fen,miao];elseresult=calJiaojian(b,a);end

在此,我们需要先定义一些基本概念。在导线测量中,我们需要测量线段长度和线段之间的夹角。在计算的过程中,我们需要注意度数的表示方式以及长度单位的转换。在本例中,我们采用了角度的度分秒表示法,并将长度单位转换为米。

在给定已知点 A、B、C、D 和观测角及水平距离 beta、L 后

% 已知点
A = [2686.681, 3744.191];
B = [2808.333, 4229.166];
C = [2882.598, 5574.768];
D = [3309.042, 5313.721];% 输入观测角和水平距离
beta = [253, 08, 0; 156, 59, 36; 135, 11, 35; 145, 38, 10; 109, 41, 51; 171, 57, 02];
L = [494.369, 554.5062, 479.280, 482.258, 459.686];
L_sum = sum(L); % 距离和

这些就是测量的数据。没什么好说的

我们需要进行坐标反算。然后,我们可以计算观测角的方位角和后方交会计算。

% 坐标反算
[Dab1, alpha1] = ZBFS(A(1), A(2), B(1), B(2));
[Dab2, alpha2] = ZBFS(C(1), C(2), D(1), D(2));

这里的ZBFS的函数实现就需要说下:
$$
设点 A 的坐标为 (xa, ya),点 B 的坐标为 (xb, yb),则点 A 与点 B 之间的距离 Dab 可以表示为:

Dab = sqrt((xb - xa)^2 + (yb - ya)^2)

设点 A 与点 B 之间的象限角为 aAB,则根据 deltax 和 deltay 的正负,坐标方位角 alpha 可以表示为:

如果 deltax > 0 且 deltay >= 0,则 alpha = aAB。

如果 deltax < 0 且 deltay >= 0,则 alpha = π - aAB。

如果 deltax < 0 且 deltay <= 0,则 alpha = π + aAB。

如果 deltax > 0 且 deltay <= 0,则 alpha = 2π - aAB。

如果 deltax = 0 且 deltay > 0,则 alpha = π/2。

如果 deltax = 0 且 deltay < 0,则 alpha = 3π/2。
$$

function [Dab,alpha]=ZBFS(xa,ya,xb,yb)
%已知A、B两点的坐标,反求两点的方位角和距离
deltax=xb-xa;%x方向坐标增量
deltay=yb-ya;%y方向坐标增量
Dab=sqrt(deltax.*2+deltay.*2);%距离
aAB=atan2(abs(deltay),abs(deltax));%象限角
if deltax>0&&deltay>=0alpha=aAB;
elseif deltax<0&&deltay>=0alpha=pi-aAB;
elseif deltax<0&&deltay<=0alpha=pi+aAB;
elseif deltax>0&&deltay<=0alpha=2*pi-aAB;
elseif deltax==0&&deltay>=0alpha=pi./2;
elsealpha=3*pi/2;
end
alpha=rad2deg(alpha);
end

这段程序用于实现坐标反算,即通过已知两点的坐标,反求两点之间的方位角和距离。

函数名为 ZBFS,参数为已知点 A 和 B 的坐标 (xa, ya, xb, yb)。

根据坐标增量计算了两点之间的距离 Dab。这里使用了勾股定理,即平方根(deltax^2 + deltay^2)。根据坐标增量的正负关系和各象限的角度定义,计算了方位角 alpha。根据坐标增量的不同情况,使用了不同的计算公式(这里测绘的应该懂)。最后,将方位角 alpha 转换为度数表示,并将方位角和距离作为函数的返回值。

通过这段程序,我们可以方便地根据已知点的坐标计算出两点之间的方位角和距离。

% 四舍五入转换为度数,采用度分秒格式
alpha1 = round(degrees2dms(alpha1));
alpha2 = round(degrees2dms(alpha2));

这里没啥好说的。

算下理论值与实际值的差距

% 计算fbeta
fbeta = fbeta(alpha1, beta, alpha2);% 计算每段需要的误差中和值
pich = fbeta / length(beta);

计算函数fbeta:

公式很简单,就是理论值相加减去实际值
f b e t a = ( a l p h a b + b e t a 1 − 180 + b e t a 2 − 180 + . . . + b e t a n − 180 ) − a l p h a c d = ( a l p h a b + ∑ b e t a i − n ∗ 180 ) − a l p h a c d fbeta=(alphab+beta1-180+beta2-180+...+betan-180)-alphacd = (alphab+∑betai-n*180)-alphacd fbeta=(alphab+beta1180+beta2180+...+betan180)alphacd=(alphab+betain180)alphacd

function result = fbeta(a,b,c)%计算线差column_sums = sum(b);fir=calJiaojia(a,column_sums);sec=calJiaojian(fir,length(b)*180);if c(1)>=270 c=calJiaojian(360,c); thi=calJiaojian(sec,c);result=-thi(3);elsethi=calJiaojian(sec,c);result=thi(3);end
  1. 首先,将参数b中的每列元素进行求和,赋值给变量column_sums。
  2. 调用函数calJiaojia,将参数a和column_sums进行角度相加的计算,将结果赋值给fir。
  3. 将参数b的长度乘以180,得到一个角度数值,然后调用函数calJiaojian,将fir和这个角度数值进行角度相减的计算,将结果赋值给sec。
  4. 如果参数c的第一个元素大于等于270,执行以下步骤:
    • 调用函数calJiaojian,将360和参数c进行角度相减的计算,将结果赋值给c。
    • 调用函数calJiaojian,将sec和c进行角度相减的计算,将结果赋值给thi。
    • 将thi的第三个元素取负值,并将结果赋值给result。
  5. 否则,执行以下步骤:
    • 调用函数calJiaojian,将sec和参数c进行角度相减的计算,将结果赋值给thi。
    • 将thi的第三个元素赋值给result。

最终,result就是计算得到的线差结果。

那么算出误差,我们就要消除,就要用gengzheng函数
b e t a i ′ = b e t a i + ( − f b e t a / n ) betai'=betai+(-fbeta/n) betai=betai+(fbeta/n)
源码:

function result=gengzheng(a,b,c)result=zeros(length(b),3);for i=1:length(b)temp = calJiao(a,b(i,:));temp(:, 3) = temp(:, 3) - c;a=temp;if temp(1)>0result(i,:)=temp;elseresult(i,:)=calJiaojia(360,temp);endend       
end
  1. 首先,创建一个大小为b行数的全零矩阵,每行有3列,将其赋值给result变量。

  2. 然后,使用一个循环来遍历b的每一行,循环变量i从1递增到b的长度。

  3. 在循环内部,调用函数calJiao,将参数a和b的第i行作为输入,计算角度并将结果赋值给temp变量。

  4. 将temp矩阵的第三列减去参数c,并将结果更新到temp矩阵中的第三列。

  5. 将temp赋值给a,更新a的值。

  6. 检查temp矩阵的第一个元素是否大于0。

    a. 如果是,将temp赋值给result的第i行。

    b. 如果不是,将temp矩阵传递给函数calJiaojia,与360进行角度相加的计算,并将结果赋值给result的第i行。

  7. 循环结束后,返回结果矩阵result。

接着,我们可以通过计算角度和长度的平差值来计算所有点的坐标增量。就是坐标方位角那一列的改正后的值,本例子差了18秒的误差,也就是算加上18秒的误差后的坐标方位角。

% 计算坐标增量的改正数
zbzl = zbzlg(L, gaizheng);
sum_zb = sum(zbzl);
function [result,radians] = zbzlg(L, jiaodu)result = zeros(min(length(L), size(jiaodu, 1)), 2);for i = 1:min(length(L), size(jiaodu, 1))radians = ((jiaodu(i,1) + (jiaodu(i, 2) / 60) + (jiaodu(i, 3) / 3600)) * (pi / 180));result(i, 1) = L(i) * cos(radians);  % 计算 x 坐标增量result(i, 2) = L(i) * sin(radians);  % 计算 y 坐标增量
endresult = round(result, 3);
end
% 求闭合差
fx = B(1) + sum_zb(1) - C(1);
fy = B(2) + sum_zb(2) - C(2);
df = [fx, fy];

最后,我们还需要判断测量结果是否超限。在此等级我们以1/4000作为阈值。判断方法是计算所有点的坐标增量和,将其加到已知点 B 实际坐标中,并计算其与点 C 的距离,判断是否小于阈值。如果小于阈值,则输出“不超限”。

[ f x 2 + f y 2 ∑ L ≤ 1 k ] [\frac{{\sqrt{{f_x^2 + f_y^2}}}}{{\sum L}} \leq \frac{1}{k}] [Lfx2+fy2 k1]

% 判断是否超限
if (sqrt(fx.^2 + fy.^2) / L_sum) <= 1 / 4000disp('不超限');
end

那么我们就求出改成后的坐标增量

% 计算改正后的坐标增量
gzhzbzl = gaidf(zbzl, df, L)

△ x b i ′ = △ x b i + [ ( − f x / ∑ L ) ] ∗ L i △ y b i ′ = △ y b i + [ ( − f y / ∑ L ) ] ∗ L i △xbi'=△xbi+[(-fx/∑L)]*Li △ybi'=△ybi+[(-fy/∑L)]*Li xbi=xbi+[(fx/L)]Liybi=ybi+[(fy/L)]Li

function result=gaidf(gz,df,L)result=zeros(length(gz),2);for i=1:length(gz)result(i,1)=gz(i,1)+(-df(1)/sum(L))*L(1);result(i,2)=gz(i,2)+(-df(2)/sum(L))*L(2);result=round(result,3);end
end

首先创建一个与 gz 矩阵长度相同的全零矩阵作为 result。循环遍历 gz 矩阵的每一行,并进行如下计算:

  1. 通过将 gz(i,1) 加上 (-df(1)/sum(L))*L(1) 的结果赋值给 result(i,1)
  2. 通过将 gz(i,2) 加上 (-df(2)/sum(L))*L(2) 的结果赋值给 result(i,2)
  3. 使用 round() 函数将 result 矩阵的所有元素舍入到小数点后三位
  4. 根据给定的 gzdfL 计算并舍入结果,然后返回结果矩阵。

四.总结

导线测量在测绘领域中具有重要的应用价值。MATLAB作为一种强大的计算机软件工具,提供了丰富的功能和工具,可以帮助我们更高效、准确地进行导线测量分析和处理。

本博客介绍了使用MATLAB进行导线测量的基本流程和方法,通过使用MATLAB进行导线测量,我们可以极大地提高测量的效率和准确性。我们可以编写自定义的函数和脚本,根据特定的测量要求进行处理和分析。同时,MATLAB提供了丰富的绘图和数据可视化功能,可以帮助我们清晰地展示测量结果,以后或许会往这方面继续开发。

然而,在实际设计中,我们需要注意测量仪器的精确性和数据的可靠性。此外,还需要注意限差的判断。

重申,本程序仅供学习,gui还需改进,若想直接用程序,可以查看我上传的资源。
完结撒花✿✿ヽ(°▽°)ノ✿

这篇关于MATLAB--导线测量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/683689

相关文章

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

libsvm在matlab中的使用方法

原文地址:libsvm在matlab中的使用方法 作者: lwenqu_8lbsk 前段时间,gyp326曾在论坛里问libsvm如何在matlab中使用,我还奇怪,认为libsvm是C的程序,应该不能。没想到今天又有人问道,难道matlab真的能运行libsvm。我到官方网站看了下,原来,真的提供了matlab的使用接口。 接口下载在: http://www.csie.ntu.edu.

R语言统计分析——重复测量方差分析

参考资料:R语言实战【第2版】         所谓重复测量方差分析,即受试者被测量不止一次。本例使用数据集市co2数据集:因变量是二氧化碳吸收量(uptake),自变量是植物类型(Type)和七种水平的二氧化碳浓度(conc)。Type是组间因子,conc是组内因子。Type已经被存储为一个因子变量,还需要将conc转换为因子变量。分析过程如下: # 将conc变量转化为因子变量CO2$c

Matlab/Simulink中PMSM模型的反电动势系数和转矩系数

Matlab/Simulink中PMSM模型的反电动势系数和转矩系数_matlab pmsm-CSDN博客

MATLAB层次聚类分析法

转自:http://blog.163.com/lxg_1123@126/blog/static/74841406201022774051963/ 层次聚类是基于距离的聚类方法,MATLAB中通过pdist、linkage、dendrogram、cluster等函数来完成。层次聚类的过程可以分这么几步: (1) 确定对象(实际上就是数据集中的每个数据点)之间的相似性,实际上就是定义一个表征

MATLAB的fix(),floor()和ceil()函数的区别与联系

fix(x),floor(x)和ceil(x)函数都是对x取整,只不过取整方向不同而已。 这里的方向是以x轴作为横坐标来看的,向右就是朝着正轴方向,向左就是朝着负轴方向。 fix(x):向0取整(也可以理解为向中间取整) floor(x):向左取整 ceil(x):向右取整 举例: 4个数:a=3.3、b=3.7、c=-3.3、d=-3.7 fix(a)=3 fl

MATLAB中的eig函数

在MATLAB中,计算矩阵A的特征值和特征向量的函数是eig(A),常用的调用格式有5种: E=eig(A):求矩阵A的全部特征值,构成向量E。 [V,D]=eig(A):求矩阵A的全部特征值,构成对角阵D,并求A的特征向量构成V的列向量。 [V,D]=eig(A,'nobalance'):与第2种格式类似,但第2种格式中先对A作相似变换后求矩阵A的特征值和特征向量,而格式3直接求矩阵A的特

MATLAB中的diag函数

diag函数功能:矩阵对角元素的提取和创建对角阵 设以下X为方阵,v为向量 1、X = diag(v,k)当v是一个含有n个元素的向量时,返回一个n+abs(k)阶方阵X,向量v在矩阵X中的第k个对角线上,k=0表示主对角线,k>0表示在主对角线上方,k<0表示在主对角线下方。例1: v=[1 2 3]; diag(v, 3) ans =      0     0     0