关于matlab

preface:

2010年11月开始跟师兄做图形学的研究。开始看图形学,看数值逼近,看微分几何。

1.数值逼近可以用matlab来做实验。

2.微分几何太抽象了,可以用matlab来画出图形看看。

3.正好师兄推荐用matlab先做些简单的图形实验。

所以这两天就用了下matlab, 下面记录一些个人认为比较有用的心得。

 

 

注释:%

块注释:

%{

注释语句(注意,'%{' 行后面与 '%}'行前面 都不能有其他字符)

%}

连接符: ...

如果一个语句在一行内书写太长了,要再下一行接着写,这时可以在上一行末尾打上半个省略号(...),然后再在下一行接着写。

比如,下面俩个语句是等价的:

       x1 = 1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6;

和    x1 = 1 + 1/2 + 1/3 +...

               1/4 + 1/5 + 1/6;

 

 

1.构造矩阵(数组)

x = [1 2 3]
x = [1 2 3; 4 5 6]

 

x = linspace(1,50)  %创建100个(默认)元素的行向量,元素值依次从1~50

x = linspace(0,0,5) %创建5个元素都是0的行向量
x = [0:2:100]  或 x = 0:2:100

 

x = zeros(m,n) %创建m*n的全0矩阵

y = x(1:3 , 2:5)  %y矩阵为取x矩阵的1~3行,2~5列的数据

y = x(:, 1:3) %y矩阵为取x矩阵1~3列的数据

 

 

2.矩阵运算

A*B    即矩阵乘法
A.*B   即矩阵对应元素相乘 (相应的,还有./等运算)
A'     即矩阵转置
inv(A) 即矩阵求逆
det(A) 即求方阵行列式

rank(A)即求矩阵的秩

 

3.参数曲线绘制 r(t)=(x(t), y(t), z(t))

eg: 
%绘制螺旋线 r(t)=(cos(t), sin(t), t) t=0:0.1:30; x = cos(t); y = sin(t); z = t; plot3(x,y,z); grid on; title('螺旋线'); xlabel('x'); ylabel('y'); zlabel('z'); 

 

 

4.参数曲面的绘制 z = f(x,y) 和 r(u,v) = (x(u,v), y(u,v), z(u,v))

eg:
%d z = f(x,y) 显式表达式 %d 绘制椭圆抛物面:z = x^2 + y^2 [x,y]=meshgrid(-2:0.2:2,-2:0.2:2); z=x.^2 + y.^2; surf(x,y,z); title('椭圆抛物面') xlabel('x'); ylabel('y'); zlabel('z');
==================================
%d r(u,v) = (x(u,v), y(u,v), z(u,v)) 参数表达式 %d 绘制螺旋面:r(u,v) = (u*cos(v), u*sin(v), v) u=linspace(0,pi,30); v=linspace(0,3*pi,30); [U,V]=meshgrid(u,v); x = U.*cos(V); y = U.*sin(V); z = V; mesh(x,y,z); title('螺旋面'); xlabel('x'); ylabel('y');

 

5.关于 mesh 与 meshgrid (surf与mesh本质一样)

 

首先,mesh只能画四边形网格(要想画三角形网格、或者其他多边形网格,就得自己用plot3等等其他或一个叫patch的函数来画了)
其次,这是对help的补充,你还是先看看matlab的help文档吧。

 

meshgrid
  用法:[X,Y]=meshgrid(x,y); [X,Y]=meshgrid(x); [X,Y,Z]=meshgrid(x,y,z);
最后一种暂时没用到,不管他;
第二种 [X,Y]=meshgrid(x) == meshgrid(x,x);
所以我们来了解第一种 [X,Y]=meshgrid(x,y);

该函数的作用是,将向量 x=[x1, x2, ... xn] 与 y=[y1, y2, ... ym] 转换成m*n的矩阵X,Y
其中,X的每行都是x, Y的每列都是y
即:
                x1 x2 ... xn                      y1 y1 ...
X[m*n] = x1 x2 ... xn   与  Y[m*n]= y2 y2 ...
                ...                                     ...
                x1 x2 ... xn                      ym ym ...

这样的效果,等于在笛卡尔坐标中将XY平面用x,y网格化了。
然后只要再对应上每个 XY平面网格交点 对应的Z值,就能画出空间上的曲面网格了。

 

mesh
  用法:mesh(X,Y,Z); mesh(x,y,Z); mesh(Z).  其中X Y Z都是m*n矩阵; x是n维向量,y是m维向量。
实际上, mesh(Z) = mesh(1:n, 1:m, Z);
    mesh(x,y,Z) = [X,Y]=meshgrid(x,y) + mesh(X,Y,Z);
    
至于 mesh(X,Y,Z),
其实如上所述,就是先通过X,Y将笛卡尔坐标的XY平面网格化,然后对应上每个交点的Z轴值,就得到我们要的网格曲面了。

PS:如果X,Y是从meshgrid得到的,那么XY平面网格就是一个个矩形的网格。
但X,Y不一定都想meshgrid得到的一样,X的每行都是x,Y的每列都是y。 这时候,XY平面网格就未必是一个个矩形了,但当然仍是四边形。(通常,像4中参数表达书获得的XY就这样。)

 

 

6. 数据的保存与读取(save & load)

save:将工作空间的所有变数储存到名为matlab.mat的二进制档案。

save filename:将工作空间的所有变数储存到名为filename.mat的二进制档案。

save filename x y z :将变数x、y、z储存到名为filename.mat的二进制档案。 

 

以二进制的方式储存变数,通常档案会比较小,而且在载入时速度较快,但是就无法用普通的文书软体(例如pe2或记事本)看到档案内容。若想看到档案内容,则必须加上-ascii选项。若非有特殊需要,我们应该尽量以二进制方式储存资料。 

 

save filename x -ascii:将变数x存到名为filename的ASCII档案。

save filename -ascii:将所有变量存到名为filename的ASCII档案。但ascii文档无法区别各个变量。

=======================

load filename:load会寻找名称为filename.mat的档案,并以二进制格式载入。若找不到filename.mat,则寻找名称为filename的档案,并以ASCII格式载入。若以ASCII格式载入,则变数名称即为档案名称。
load filename -ascii:load会寻找名称为filename的档案,并以ASCII格式载入。    

 

7. 用patch绘制

patch图形对象是由一个或多个多边形(连接或不连接的)组成的。patchs在真实物体的建模中非常有用,比如飞机,汽车的建模。它还能绘制任意形状的二维三维多边形。

相比之下,surface对象是由四边形网格组成的,更适合于显示平滑的图形,比如绘制数学上的二元函数值的图形。

 

patch的用法参考help。

这里贴一个Defining a Cube的例子。

 

 

一个立方体有8个顶点、6个面。如下图所示:

 

关于matlab_第1张图片

 

 

 

1. 如果我们将xyz坐标参数定义为行向量形式。

那么不幸的是,他们将会被简单地识别成由每个顶点直接连接起来的单个“多边形。”

X = [0 1 1 0 0 0 1 1]

Y = [0 0 1 1 1 0 0 1]

Z = [0 0 0 0 1 1 1 1]

patch(X,Y,Z,’y’);

 

 

2.如果xyz坐标参数 是由矩阵[m*n]表示的话,MATLAB用三个矩阵对应的每列绘制一个多边形face(每个face可以由m个点),然后通过着n列的nfaces组成一个patch。这些faces可以不是连接的,并且可以自交叉。

因为立方体有六个面,每个面四个点。所以这时xyz坐标矩阵为4*6; 每一列代表一个face。如下图所示:

 

 

从上面我们可以注意到,一个立方体其实只需要8个顶点,但是用这种方法却需要4*6=24个顶点来定义,消耗太大。所以我们引入Vertices Faces属性。

 

3. Specifying Faces and Vertices。如下图所示:

关于matlab_第2张图片

 

 

 

使用这种方法能大量降低消耗,尤其当patches有大量的faces的时候。这种方法要求用户调用更正式的patch函数定义VerticesFaces属性,比如:

            patch('Vertices',vertex_matrix,'Faces',faces_matrix)

因为这种语法不会自动定义faceedge的颜色,所以用户需要调用set函数来设置这些颜色属性,如果不想使用默认的白色face和黑色edge的话。

 

Reamark

 

l         如果坐标参数未能定义一个闭合的多边形,patch能自动闭合该多边形。

 

l         MATLAB并不要求每个面都有相同的顶点数。如果当有些faces的顶点数与其他不同时候,将这些顶点数较少的facesNaN填充成一样多的顶点数即可。

eg:  Faces = 

 

 

8. 可变长参数的函数

参见help中的  varargin, varargout 和 nargin, nargout 

 

 

9. GUI中的交互

鼠标交互:
对于菜单对象,鼠标操作可以激活菜单的callback属性;

对于控件对象,鼠标操作可以激活控件对象的callback属性与ButtondownFcn属性;

对于图形窗口对象,鼠标操作可以激活图形窗口的ButtondownFcn属性、WindowButtondownFcn属性、WindowButtonmotionFcn属性和WindowButtonupFcn属性。
 

获取鼠标位置:
get(gca, 'currentpoint')


一个用鼠标画线的例子: 

function interplot %funway:这事一个画橡皮线的实例程序。里面有交互信息。 global istep %记录鼠标点击数。(1画线头,2画线尾然后清0) global xdata global ydata istep = 0; set(gcf, 'pointer', 'cross'); set(gcf, 'WindowButtonDownFcn', @WindowButtonDown); set(gcf, 'WindowButtonMotionFcn', @WindowButtonMotion); function WindowButtonDown(hObject, eventdata, handles) global istep global xdata global ydata global h istep = istep + 1; p = get(gca, 'currentpoint'); %获取当前坐标系上的currentpoint属性,gca获得当前坐标系句柄 disp('CLICK! gca currentpoint:'); disp(p); if(istep == 1) xdata(1) = p(1,1); ydata(1) = p(1,2); xdata(2) = p(1,1); ydata(2) = p(1,2); h = line(xdata,ydata, 'EraseMode', 'xor'); elseif(istep == 2) xdata(2) = p(1,1); ydata(2) = p(1,2); set(h, 'XData', xdata, 'YData',ydata, 'EraseMode', 'normal'); istep = 0; end function WindowButtonMotion(hObject, eventdata, handles) global istep global xdata global ydata global h p = get(gca, 'currentpoint'); disp('MOVE! gca currentpoint:'); disp(p); if(istep ==1) xdata(2)=p(1,1); ydata(2)=p(1,2); set(h, 'XData',xdata, 'YData',ydata); end

 

 

10. 关于对象句柄

10.1 句柄图形对象的层次结构

 

 关于matlab_第3张图片
10.2 每个控件对象都有一个句柄(即ID)
gcf 获得当前figure句柄(当前窗口)     ( = get(0, ‘CurrentFigure’) )
gca 获得当前坐标轴的句柄             ( = get(gcf, ‘CurrentAxes’) )
gco 获得当前控件句柄                 ( = get(gca, ‘CurrentObject’) )
get(handle) 获取句柄对象的各个属性
set(handle) 设置句柄对象的各个属性
findobj 函数通过属性值来查找对象  (eg: text_handle = findobj(‘String’, ‘xxx’) )
copyobj 函数用来复制对象
delete 函数可以用来删除对象  (eg: delete(gca) )

 

 

 

10.3 句柄对象的Callback属性
对象的callback属性通常指向一个函数(称为回调函数)。用作句柄对象的回调函数的function必须至少定义两个输入参数,一个是触发该回调函数的对象句柄,一个是触发事件数据结构。不论什么时候执行callback,matlab都会传递这两个变量。 例如:
  function myGui
  set(gcf, ‘WindowButtonDownFcn’, @myCallback);
  %@格式为函数句柄(类似C中的函数指针)

  function myCallback(obj, eventdata)

 

当然,回调函数还能添加其他参数。例如 function myCallback(obj, eventdata, arg1, arg2)
要想使用其他参数,有如下两种办法:

1.将对象句柄的callbak属性值设置为单元数组。 例如
  figure(‘WindowButtonDownFcn’,
{@myCallback, arg1, arg2} )

2.通过guidata() 来传递其他参数。 例如
  function myCallback(obj, eventdata, handles)
  handles = guidata(obj);

 

通过GUIDE设置的默认的回调函数通常为如下格式:
XXX_Callback(hObject, eventdata, handles)
  hObject 为触发该函数的控件的句柄
  eventdata 保留,为以后版本使用
  handles 通常包括所有的控件句柄,还可以用来存储传递用户自定义的数据。
(注意:自动设置的回调函数已经默认通过guidata(hObject)传递handles参数了,你可以在调试中get查看。但是如果是自定义的回调函数。就必须通过上面说的两种方法传递)


11. Mechanisms for Managing Data

11.1 guidata

 

 

你可能感兴趣的:(function,matlab,callback,图形,patch,网格)