Matlab项目经验分享-坐标系转换app设计

在以前我刚学matlab的时候,我内心是拒绝的!因为本科时候学过C、C#、Java、前端Web等,所以研一刚接触matlab的时候,对matlab甚是鄙视,心里想:matlab也算是编程语言?
读研一年半,用matlab跟老师做了一些项目之后,慢慢的不烦matlab了,matlab中自带的函数很多很多,对于需要科研建模的人来说可是神器,去年半年学习了GUI和APP的设计,嗯!
挺好玩的,做的东西还要用来写文章,所以就先不分享发了。在做项目过程中遇到了一个小小的问题,坐标系转换问题,我看网上分享方法的人很多,但是真正用程序实现的貌似没有,
更没有用界面展示出来的了。我把我做的东西分享出来给需要的朋友们作为一个示例吧。当然我也是得到了我的导师王老师的帮助写出来的!!!(这段话无关程序,可跳过

  处理问题步骤:      
        1. 抛出问题
        2. 思考解决方法
        3. 代码验证看结果
  1. 抛出问题

    在做项目的时候会遇到这样一个问题:我们的样品在显微镜下有自己的坐标系,去给样品打激光的时候,人家又有人家的坐标系,每次都要人工去找样品位置进行对号,过于麻烦,
    那能不能搞一个程序实现坐标系转换呢,把我们的坐标输进去,直接把他们的坐标导出来,自动实现坐标点对号。emmmm··· 这样说可能不太清楚我的目的,这样说吧,坐标系一
    和坐标系二是不同的坐标系,他们之间的坐标点怎么转换呢,可能需要平移,可能需要旋转,可能需要伸缩,这些都要考虑到。学过地信的Gis和RS的课的应该会了解空间坐标系的
    转换方法,用ENVI或者Arcgis可以实现空间坐标系的转换,我们只考虑二维平面的情况,不考虑三维。先看一下界面设计吧

  2. 思考解决问题

    解决办法就是常规的方法:坐标系平移、坐标系伸缩、坐标系旋转。这些原理网上多的是,我就不复制了,网上的这些算法都是一样的,我直接上干货,你们拿去就可以直接用。

         1.给定原始坐标系的两个不同点的坐标r1(x1,y1)、r2(x2,y2)和转换后的坐标系两个不同点的坐标R1(X1,Y1)、R2(X2,Y2)。
         2.输入原始坐标系的坐标集,程序直接输出转换后坐标系的坐标集
    

  3. 直接上代码吧
    我给大家两套代码,第一套是.m文件,代码简洁,想图方便的可以直接复制去用,第二套是制作坐标系转换app的具体流程,相对更复杂但是美观好操作。

    3.1 第一套简单版代码
    
         function result = Test( r1, r2, R1, R2)
         %坐标系转换系统
    
         % Input:
         %           r1, r2, [x, y], 坐标系一参考点坐标
         %           R1, R2, [X, Y], 坐标系二参考点坐标,对应r1, r2
         %           p, [x, y], 原始坐标系中坐标的集合[x, y]
    
         % Output:
         %           P [X, Y], 输出转换后坐标系的坐标集合,对应p
    
    
         % 参考点, R1, R2,(x, y)=> 和(X, Y)
         % r1: [x1, y1] => R1: [X1, Y1]
         % r2: [x2, y2] => R2: [X2, Y2]
    
         % 求p: [x, y] 转换至P [X, Y]?
    
         %% 坐标平移, r2平移至R2
         dr2R = R2 - r2; % 平移向量
    
         Rr1 = r1 + dr2R; % r1在R坐标系的坐标,以R2为原点向量
         %Rr3 = r3 + dr2R;
         %Rr2 = [0, 0];
    
         % 读取自己文件夹中的excel表格xls文件,记得改成自己的文件夹
         [num]=xlsread('D:\WorkSoftWare\MATLAB2020\bin\workspace\坐标系转换\test.xls');
         % 获取excel中坐标的长度(看有多少个坐标点)
         a = size(num,1);
         % 创建空集合用来存放转换后的坐标
         PP = [];
         % 做迭代进行转换
         for i = 1:a
         p = num(i,:);
         Pmoved = p + dr2R; % 平移操作
         % [X, Y, 1] = [x, y, 1]*[1, 0, 0; 0, 1, 0; dx, dy, 1];
    
         %% 坐标旋转
         VR21 = R1 - R2;
         Vr21 = Rr1- R2;
         % VR23 = R3 - R2;
    
         cosR1 = dot(VR21, Vr21)/norm(VR21)/norm(Vr21);    % 点乘,锐角正,钝角负,不分方向
         sinR1 = cross( [Vr21, 0], [VR21, 0]  )/norm(VR21)/norm(Vr21);  % 叉乘(三维),cross(A,B), 右手法则,在XY平面判断A-B旋转关系
         Rot = [cosR1, sinR1(3); -sinR1(3), cosR1]; % 旋转向量
    
    
         Protated =  (Pmoved-R2)*Rot; % 矩阵相乘
    
         % 坐标缩放
         Zoom = norm(VR21)/norm(Vr21);
         P = R2 + Protated*Zoom;
         PP(i,:) = P;
    
         end
         % 输出转换后的坐标集合到文件夹,记得也要换成自己的文件夹
         dlmwrite('C:\Users\13222\Desktop\out.xlsx',PP,"\t");
         end
    

    3.2 第二套app界面版程序设计流程

    a.右键文本输入区进入回调函数

         function TextArea_2ValueChanged(app, event)
               r1x = str2double(app.TextArea_2.Value);
               if isnan(r1x)
                   errordlg('ModelStartY非数字字符输入,请重新输入','输入错误');
               else
                   setappdata(app.UIFigure, 'r1x', r1x);
               end           
          end
         这八个空都用这样的形式来获取输入文字的值,这是matlabapp获取文本输入的方式
    

    b.右键‘导入excel’按钮进入回调函数

         function LoadexcelButtonPushed(app, event)
               [filename, pathname] = uigetfile('*.xls');
               LoadFilename = [pathname,filename];
               setappdata(app.UIFigure,'LoadFilename',LoadFilename);
               app.LoadFilenameTextArea.Value = getappdata(app.UIFigure,'LoadFilename');
               num = xlsread(LoadFilename);
         
               app.UITable.Data = num;
               % 在坐标系中画出坐标点
               plot(app.UIAxes,num(:,1),num(:,2));
           end
         这个函数是获取原始坐标系的Excel的xls文件,里面是原始坐标系的坐标的集合。
    

    c.右键‘输出excel’按钮进入回调函数

         % Button pushed function: OutputexcelButton
           function OutputexcelButtonPushed(app, event)
         
               % 获取r1 r2 R1 R2 的x,y坐标
               r1 = [getappdata(app.UIFigure,'r1x'),getappdata(app.UIFigure,'r1y')];
         
               r2 = [getappdata(app.UIFigure,'r2x'),getappdata(app.UIFigure,'r2y')];
         
               R1 = [getappdata(app.UIFigure,'R1X'),getappdata(app.UIFigure,'R1Y')];
         
               R2 = [getappdata(app.UIFigure,'R2X'),getappdata(app.UIFigure,'R2Y')];
         
         
         
               dr2R = R2 - r2; % 平移向量          
               Rr1 = r1 + dr2R; % r1在R坐标系的坐标,以R2为原点向量
         
               % 读取原始坐标系统中的x,y坐标集合的excel
               LoadFilename = getappdata(app.UIFigure,'LoadFilename');         % 文件名      
         
               [num] = xlsread(LoadFilename);                                  % 读取数据
         
               a = size(num,1);                                                % 数据长度
         
               PP = [];                                                        % 建立空集合用来存放转换后的坐标系坐标
         
               % 迭代转换
               for i = 1:a
                   p = num(i,:);
                   Pmoved = p + dr2R; % 平移操作
                   % [X, Y, 1] = [x, y, 1]*[1, 0, 0; 0, 1, 0; dx, dy, 1];
             
                   %% 坐标旋转
                   VR21 = R1 - R2;
                   Vr21 = Rr1- R2;
                   % VR23 = R3 - R2;
             
                   cosR1 = dot(VR21, Vr21)/norm(VR21)/norm(Vr21);    % 点乘,锐角正,钝角负,不分方向
                   sinR1 = cross( [Vr21, 0], [VR21, 0]  )/norm(VR21)/norm(Vr21);  % 叉乘(三维),cross(A,B), 右手法则,在XY平面判断A-B旋转关系
                   Rot = [cosR1, sinR1(3); -sinR1(3), cosR1]; % 旋转向量
             
             
                   Protated =  (Pmoved-R2)*Rot; % 矩阵相乘
             
                   % 坐标缩放
                   Zoom = norm(VR21)/norm(Vr21);
                   P = R2 + Protated*Zoom;
             
                   % 存放新坐标
                   PP(i,:) = P;
                                           
                   end
         
               % 将转换后的坐标输出为excel表
               dlmwrite('C:\Users\13222\Desktop\out.xlsx',PP,"\t");
         
               % cla(app.UIAxes);
               % 画出坐标点位置                     
               Fig = app.UIFigure;
               figure(Fig);            
               hold(app.UIAxes,'on');
               plot(app.UIAxes,PP(:,1),PP(:,2),'r.');          
           end
           按照这个顺序就可以实现坐标系转换的app设计了,来吧 展示
    

    d.运行程序,先输入原始坐标系,会展示Excel数据和坐标点的折线图

    e.输入原始坐标系的两个参考点r1、r2和转换后坐标系的两个参考点R1、R2,会输出转换后的Excel,并展示转换后的坐标点图像,并和原始数据进行对比

    f.test是输入的原始坐标系的Excel,out是输出的转换后坐标系的Excel

    写到这程序就差不多了,我得承认一点,这个程序是我几个小时搞出来的,时间少,最大的一个缺陷就是时间复杂度很高,算法不是很简便,需要多次迭代,数据少一点还是没事的,
    在一个就是这篇文章,写的也紧,时间少,很粗糙,我也不检查了,有错别字什么的见谅!!!

    最后我想说的是:matlab作为科研的建模计算工具是真不错,简单且功能强大,科研人员可以学习使用,但是我不能算一个科研人员,因为我对科研尤其是地质方面的科研没有丝毫
    的兴趣,我钟爱强大的Java。

posted @ 2021-01-11 11:04  感情是渐变色的  阅读(629)  评论(0)    收藏  举报