Showing posts with label 動畫. Show all posts
Showing posts with label 動畫. Show all posts

2/16/07

9.1 滾動的車輪

滾動的車輪


要讓輪子能夠轉動,並且在一個平面上滾動,尚必須熟悉其他有關指令。在MATLAB中,並沒有繪圓的指令,雖然有做立體球之相關指令,但純為繪圓則必須自己寫。我們已經在MATLAB論壇中公佈了一個繪圓的指令:

>>circle(r, x0,y0)

實際上,圓之程式可以利用下列指令簡單完成:


xx=[r*cos(th) 0];yy=[r*sin(th) 0];


其中加上[0 0]這點圓心,主要目的是要加上一條半徑線,使圓之迴轉可以看得出來。圓型的物體在平面上滾動時,其行走之圓周長應等於前進之距離。周長為半徑與迴轉弧度之乘積。其運動之軌跡因此可以利用此一關係計算。

話說要使一個輪子在平面上滾動,其一輪子必須移動,其二輪子必須自轉。這兩個動作必須合併進行。前面已經談過,移動與轉動必須借助trans4這個函數指令,並且呼叫兩次。而每次的座標轉換,應先在原點上自轉後再將座標移動到需要的位置,如此才能使過程簡化。

程式內容


車輪滾動時,中間有一半徑作為指標。車輪由兩圓組成,其握把分別為h及h1,一為實線,一為虛線。使車輪有滾動的感覺。當車輪滾至兩端時,會返回,使其維持在同一平台上。

function rolling_wheel(r,v)
% circle motion
% Example: rolling_wheel(10,10)
clf;
ww=max(100,3*r);
axis([-r ww+r 0 r]);
axis equal;axis off;
ss=100/pi/3;
th=linspace(0,2*pi,120);
xx=[r*cos(th) 0];yy=[r*sin(th) 0];
line([-r ww+r]',[0 0]','linewidth',3,'color','b');
h=line('xdata',[],'ydata',[],'erasemode','xor',...
'linestyle','-.','linewidth',6,'color','r');
h1=line('xdata',[],'ydata',[],'color','b','linewidth',4);
title('Rolling Wheel (Press Ctl-C to stop)');
s=pi/120*v;sth=0;d=0;
while 1,
x=xx*cos(sth)-yy*sin(sth)+d;
y=xx*sin(sth)+yy*cos(sth)+r;
set(h1,'xdata',x,'ydata',y);
set(h,'xdata',x,'ydata',y);
sth=sth-s; d=-r*sth;
if sth>0|d>ww, s=-s;end;
drawnow;
pause(0.01);
end



執行結果




環內迴轉


除了在直線迴轉之情況下,亦可考慮在圓圈內迴轉時之情形如下:

function rolling_wheel2(r1,r2,v)
% circle motion
% Example: rolling_wheel2(15,30,1)
clf;
axis([-r2 r2 -r2 r2]);
axis equal;axis off;
ss=100/pi/3;
t0=linspace(0,2*pi,360);
h0=line(r2*cos(t0),r2*sin(t0),'linewidth',3,'color','b');
h=line('xdata',[],'ydata',[],'erasemode','xor',...
'linestyle','-.','linewidth',max(1,ceil(r1/5)),'color','r');
t1=linspace(0,2*pi,120);
xx=[r1*cos(t1) 0];yy=[r1*sin(t1) 0];
title('Press Ctl-C to stop');
s=pi/120*v;sth=0;th=0;

while 1,
dx=(r2-r1)*cos(th);
dy=(r2-r1)*sin(th);
x=xx*cos(sth)-yy*sin(sth)+dx;
y=xx*sin(sth)+yy*cos(sth)+dy;
set(h,'xdata',x,'ydata',y);
th=th-s;
sth=sth+s*r2/r1;
if sth>2*pi,sth=sth-2*pi;end
if th>2*pi,th=th-2*pi;end;
drawnow;
pause(0.01);
end

執行結果




由這個例子中,除了因桿長不同可以看出擺線的位置不同外,同學亦可思考其應用方向,例如:
  1. 將桿子(握把h1)變換為一個人的形式,會有什麼不同?
  2. 將n值作成n=3在地面上滾動時,會產生那些不合理的地方?若有應如何修正?
  3. 能否將平面改成一個已知的曲面,使圓輪在曲面內滾動?
  4. 如果圓輪與地面有打滑時(例如打滑率3%),則程式如何修正以反應此點?

9.2 旋轉的風扇

會旋轉的風扇是葉片的變換而已,這是一個明顯的機動學例子,也可以看出它是一個純轉動的狀況。為製造出葉片的數目,必須先作出一個葉片的形狀,然後令其轉動數次,以求得整個葉片的座標。

x=[1 2 1 -3 -1]';y=[1 7 10 11.5 1]';%propeller shape
x0=x;y0=y;
for i=1:6,
theta=60*i;
xy=trans4([x0,y0],theta,5);
x=[x; xy(:,1)];y=[y;xy(:,2)];
end;

第一行是單片葉片的外圍形狀座標點,可由同學自行決定。然後利用這些座標旋轉6次,每次轉動60度,成為一圈所需的葉片座標。特別注意的是各座標均為行矩陣,故累加時亦必須轉成行矩陣才能相加。其餘的程序與前面各例的手法大致相同。只是這個函數有個速度參數v,可以決定該葉片的轉動速度。

程式內容


此程式呼叫一小程式circ(r),是以原點出發,以某一輸入半徑r繪圓的函數。其傳回之參數為該圓之握把h。主程式中共呼叫circ三次,第一次h0為風扇輪轂之外圈,為黑色之厚圓。第二次為葉片之內輪h1,第三次為葉輪之外圓h2,後兩者均可以隨葉片迴轉。

function demo_mot8(v)
%demo_mot8.m
%Moving propeller
%Example: demo_mot8(10)
%Author:DSFon, BIME,NTU. Date:Jan. 24, 2007
clf;
x=[1 2 1 -3 -1]';y=[1 7 10 11.5 1]';%propeller shape
x0=x;y0=y;
for i=1:6,
theta=60*i;
xy=trans4([x0,y0],theta,5);
x=[x; xy(:,1)];y=[y;xy(:,2)];
end;
delt=pi/30; %delaying time for display
axis([-15 15 -15 15]);
axis image;axis off;
h0=circ(13);set(h0,'linewidth',8,'color','k');
h1=circ(1); %the inner circle, r1
h2=circ(12.2); %The outside circle, r2
h11=line(x,y,'erasemode','xor','color','r','linewidth',5);
x1=get(h1,'xdata');y1=get(h1,'ydata'); % (x1,y1)for inner circle
x2=get(h2,'xdata');y2=get(h2,'ydata'); % (x2,y2)for outer circle
x11=get(h11,'xdata');y11=get(h11,'ydata');%(x11,y11)for propeller
set(h1,'EraseMode','xor','color','r','linewidth',3,'linestyle',':')
set(h2,'EraseMode','xor','color','b','linewidth',5,'linestyle','-.')
title('Press Ctl-C to stop');
theta1=0;s1=v*delt;
while 1,
drawnow;
pause(0.01);
theta1=theta1+s1;
z1=trans4([x1',y1'],theta1,5);
set(h1,'xdata',z1(:,1),'ydata',z1(:,2)); % inner circle
z2=trans4([x2',y2'],theta1,5);
set(h2,'xdata',z2(:,1),'ydata',z2(:,2)); % Outer circle
z11=trans4([x11',y11'],theta1,5);
set(h11,'xdata',z11(:,1),'ydata',z11(:,2)); % propeller
if theta1>2*pi,theta1=theta1-2*pi;s1=-s1;end;
end
function h=circ(r)
th=linspace(0,2*pi,50);
h=line(r*cos(th),r*sin(th));

執行後,其迴轉情況如下面之映像:

9.3 兩輪接觸滾動

兩輪接觸滾動,雖然在機動學中不常見,但其基本觀念則是齒輪的運動狀態。

這個範例所用到的程式函數與前面之單圓滾動之情形相同,但由於兩輪的直徑可能不同,兩輪的中心可以置於水平線上。表面上看來,這兩個輪子僅是作固定位置旋轉,不必作任何平移動作。實際則不然,因為座標的原點不可能放在兩個輪的軸心上,若然,亦僅能將其中一個置於原點,另一個還是要進行平移。

本題目係將座標置於兩輪之接觸點上,因此各輪均要平移與轉動。目前因為兩輪均是圓的,故轉動起來,即使採用座標轉動的變化也看不出來,當然投機取巧不讓它轉動也是可以的,但將來若表面是有齒輪面的話,也必須表現出來。

為使表現能夠明顯。因此在各輪上設有一個徑向把,可以看出其真正轉動情形。其初始動作如圖4所示。

這個函數有三個參數,前二者為二輪之半徑,後者為r1轉動的速度。

<3>程式內容
這個程式呼叫circle函數,也是繪圓,與前面的circ功能相同,也是屬不同的寫法。讀者可以印證其功能。兩主圓分別為h1及h2,分別使用藍色與紅色;且為突顯其轉動狀態,特別改用虛線。其次是利用h11與h21分別設定兩桿,注意各桿之兩端均有標記,其型式也是以圓圈。

控制兩圓迴轉之速度為s1與s2,其關係與兩圓之半徑有關,故可以利用下式計算:

theta1=theta1+s1;
theta2=theta2-s1*r1/r2;

程式內容


每個圓圈之迴轉則利用tans4這個副程式。這個程式內容在上一節中已經有討論過,可以參考。亦可自行撰寫簡單的程式應用。

function demo_mot7(R1,R2,v)
%demo_mot7.m
% Inputs:R1,R2:radius of two circles
% v: speed of rotation
%Two matched cicles in motion
% Example: demo_mot7(50,100,2)
%Author:DS Fon, Bime. NTU Date: Jan. 24, 2007
if nargin==0,R1=50;R2=100;v=100;end
clf;
r1=min(abs(R1),abs(R2));
r2=max(abs(R1),abs(R2));
height=max(r1,r2)*1.5;
axis([-2.5*r1 2.4*r2 -height height]);
axis image;axis off;
line([-2*r1 2*r2]',[0 0]','color','k',...
'linewidth',1,'linestyle','-.'); %The ground line
circle(r1/4,r2,0,10);circle(r1/4,-r1,0,10);
h1=circle(r1,0,0); %Draw the 1st circle of radius r1
h2=circle(r2,0,0); %Draw the 2nd circle of radius r2
h11=line([0 r1]',[0 0]','erasemode','xor','color','b',...
'linewidth',4,'marker','o','markersize',8); %Rod 1
h21=line([0 -r2]',[0 0]','erasemode','xor','color','r',...
'linewidth',8,'marker','o','markersize',16); %Rod 2
hold on;
%Get coordinates (x1,y1) & (x2,y2) of both circles
x1=get(h1,'xdata');y1=get(h1,'ydata');
x2=get(h2,'xdata');y2=get(h2,'ydata');
x11=get(h11,'xdata');y11=get(h11,'ydata');% rod 1
x21=get(h21,'xdata');y21=get(h21,'ydata');% rod 2
set(h1,'EraseMode','xor','color','b',...
'linewidth',1,'linestyle','-.')
set(h2,'EraseMode','xor','color','r',...
'linewidth',2,'linestyle','-.')
grid on;
title('Press Ctl-C to stop');
theta1=0;theta2=0;s1=v*pi/20;
while 1,
drawnow;
pause(0.1);
theta1=theta1+s1;
theta2=theta2-s1*r1/r2;
z1=trans4([x1',y1'],theta1,5);%rotate circle 1
z1=trans4(z1,[-r1 0],1);%translate circle 1
z2=trans4([x2',y2'],theta2,5);%rotate circle 2
z2=trans4(z2,[r2 0],1);%translate circle 2 to (r2,0)
z11=trans4([x11',y11'],theta1,5);%rotate rod 1
z11=trans4(z11,[-r1 0],1);%translate rod 1 to (-r1,0)
z21=trans4([x21',y21'],theta2,5);%rotate rod 2
z21=trans4(z21,[r2 0],1);%translate rod 2 to (r2,0)
set(h1,'xdata',z1(:,1),'ydata',z1(:,2)); % circle 1 data
set(h2,'xdata',z2(:,1),'ydata',z2(:,2)); % Circle 2 data
set(h11,'xdata',z11(:,1),'ydata',z11(:,2)); % Rod 1
set(h21,'xdata',z21(:,1),'ydata',z21(:,2)); % Rod 2
if theta1>2*pi,theta1=theta1-2*pi;s1=-s1;end;
end

function h = circle(r,x0,y0,nn)
% The inputs:
% r = radius of circle
% x0, y0= coordinates of the circular center
% Example: circle(10,0,0,10)
if nargin==3,nn=50;end;
t=0:2*pi/nn:2*pi;
h=line(x0+r*cos(t),y0+r*sin(t));


執行結果





看看這個例子,同學可以思考未來還可加一些什麼,因為可用的指令都有了。想一想較困難的吧,諸如:

  1. 把一個人字形的人圖像放在圓圈中央,讓它耍把戯。
  2. 試著在輪外圍加上齒輪的外形,其外形僅作一個就好,其餘用轉動拷貝的,如此就可以作成實際的齒輪動作了。
  3. 能否加上第三個輪,其變換方向又有不同。
  4. 能否作一個齒輪組。
  5. 不知將圓輪變成多角形時會怎樣?

1/22/07

第二章 動畫之製作

機動學中,物件之動作與位置變化是重要的考慮。如何利用Matlab之動畫功能,以瞭解物件之動作過程,也是重要的一環。動畫之中必須配合繪製物件,其中包括圓形、矩形及線形等,這些繪圖方法及語法,已在另外章節加以說明,讀者可以參考。目前在此處比較重要的是繪出物件之示意圖,所用之工具也較為簡單。


線為圖之基礎,適當地組合線群可以形成複雜的圖形。畫線指令line可以完成這項任務。繪線必須有起始點及終止點,但若有連續的點,採用矩陣表示時,則會 自動連線,繪出整個圖形。故若使用line指令,應可以利用點群之座標,一筆畫繪出需要的圖形。多點連線時,參數可以矩陣表示,但每行代表一線,亦亦採用 多行,形成方形矩陣,下面為其一例:

2.1.1 簡單之線圖


實例1.1:若x=[1 3 5]; y=x²

>> x=[1 3 5],y=x.*x
x = 1 3 5
y = 1 9 25

>> line(x',y')
>> line(x,y)
>> grid on


圖2.2 一維向量之繪圖

2.1.2一筆畫線


利用line之功能可繪製一筆畫之圖形。這種畫法可以利用方格紙先將初稿繪於其上,然後點出其對應座標,即可利用上述line之畫線功能繪製圖案。這種圖案未來可作為程式中應用之基本元件,構成更複雜的機構。以三角形為例,可以將座標分為對應之兩行如下:

triangle=[0 0;1 0;0 2;-1 0;0 0];

其中頭尾均為共同點,以保證整個圖為封閉區線。

實例1.5: 繪出三角形



>> triangle=[0 0;1 0;0 2;-1 0;0 0]
triangle =
0 0
1 0
0 2
-1 0
0 0
>> line(triangle(:,1),triangle(:,2))
>> axis equal
>> line(triangle(:,1),triangle(:,2))


圖2.3 繪出一三角形

實例1.6:星形



>> star5=[4 0;-3.2361 2.3511;1.2361 -3.8042;1.2361 3.8042; -3.2361 -2.3511;4 0];
>> line(star5(:,1),star5(:,2))
>> axis equal %調整座標之比例使成1:1



圖2.4 繪出一星形

實例1.7:房屋



>> house=[25 94;8 56;8 16;44 5;44 52;44 5;60 16;72 12;92 28;...
92 62;92 28;72 12;72 60;72 12;60 16;60 50;60 25;...
48 16;56 21;56 40;48 36;48 16;44 16;16 40;36 36;...
36 52;16 56;16 40;8 50;2 46;24 96;48 44;62 52;52 72;...
60 88;76 52;96 64;80 96;60 88;68 92;60 108;24 96];
>> line(house(:,1),house(:,2))
>> line(house(:,1),house(:,2))
>> axis equal



圖2.5 房屋

實例1.8:斗笠



>> banhat=[0 0;5 0;2 1;0 3;-2 1;-5 0;5 0;4 0;2 1;1.5 0.99;1 0.96;...
0 0.94;-1 0.96;-1.5 0.99;-2 1;-4 0;-3 0;-1.5 0.99;0 3;...
-0.5 0.95;-1 0;-2 0;-1 0.96;-2 0;2 0;1 0.96;2 0;1 0;...
0.5 0.95; 0 3;1.5 0.99;3 0;4 0;2 1;1.5 0.99;0 3;0 0];
>> line(banhat(:,1),banhat(:,2))
>> line(banhat(:,1),banhat(:,2))
>> axis off
>> axis equal


圖2.6斗笠


利用上述之方式,應該可以創出許多不同的作品,唯一需要的是個人的創意。

2.3 連桿外型之繪製

連桿之位置及其外觀設計如下圖。連桿兩端之中心點分別為AB,由此兩點界定連桿之尺寸。因此其兩點間之距離D為重要的因素。由於繪製連桿之外圍,必須利用line指令採用描線之方式。這裡所提出之描線方法與前節介紹之內容相同,是屬最簡單之方式。首先設連桿之厚度為d,兩端之外圓與內圓之半徑分別為d/2與d/4。其連線方式由左邊之A點開始,先往上走1,再繞左端之內圓,回到原端點時再往上走3。至外圓時往左走半圓4,經過5,與右邊之半圓6 ,至7往下再走內圓8,其次回到9往上,再往右沿10回到3,完成一線畫。



由於連桿係以平放的位置開始,實際上必須計算BA線段之角度,然後進行迴轉到所需要之位置。此時就必須利用第一章之座標轉移與迴轉,配合運用。

程式內容


為使任何連桿均能具有厚度,以及所需要之長度,程式linkshape就是一種函數寫法,並且主要能繪出連桿之外形。此函數之輸入有點A、B與d三項,分別為連桿之起點及終點座標及桿厚度。程式採用複數表示法,因此可以迅速計算其D值與傾斜角度。

在Matlab中,複數表示法有其特殊的性質,可以作為表示兩獨立座標之值。在複數表示法中,實數i的對應值可代表x軸之向量;而虛數j部份之值可代表y軸之向量,因此在二維的座標中,正好可以利用一個複數值代表一個座標點。其優點是Matlab中有指令如real()、imag()、abs()、angle()等函數可以分別處理實數、虛數、絕對值及角度等值,應用上有其方便之處。所以在linkshape之函數中,可以見證其應用的情形。

連桿AB間,其對應關係式可以轉換如下:

x = x'cos(th)-y'sin(th) +A(1)
y = y'sin(th)+y'cos(th) +A(2)

公式裡,th為其水平角度,A(1)與A(2)分別為起點A之座標值。程式內容如下:

function linkshape(A,B,dd)
% Draw a link
% Inputs:
% A,B:Initial & final coordinates of link
% d:thickness of link(negative for line link)
% Example: linkshape([0 0],[5,5])
if nargin==2,dd=1;end;
d=abs(dd);
AB=(B(1)+j*B(2))-(A(1)+j*A(2));
D=abs(AB);th=angle(AB);
t=linspace(pi/2,2.5*pi,20);
Cout=max(d/2,0.2)*exp(j*t');Cin=Cout/2;
if dd>0,
P=[0;Cin;Cout(1:10);D+Cout(11:20);D+Cin;D+Cout(20);Cout(1)];
else
P=[Cin;0;D;D+Cin];
end
xx=real(P);yy=imag(P);
x=xx*cos(th)-yy*sin(th)+A(1);
y=xx*sin(th)+yy*cos(th)+A(2);
line(x,y)
axis equal

執行例



>> linkshape([15 0],[0,0])
>> linkshape([15 0],[5,6])
>> linkshape([0 0],[5,6])




利用同樣的程式,試執行下列指令,看看會有什麼樣的結果。

>> linkshape([15 0],[0,0],-1)
>> linkshape([15 0],[5,6],-1)
>> linkshape([0 0],[5,6],-1)


設有一四連桿,其ABCD四點之座標分別為A(0,0);B(3,4);C(13,4);D(10,0),其單位為cm,若AD為固定桿,AB為第二桿BC與CD分別為第三與第四桿,各桿厚度分別為3,2,1,3cm。試繪出其相關位置。

若AB為主動迴轉桿,則其每間隔60度間之對應位置會如何?這可寫成一個執行檔如下:

linkshape([0 0],[10 0],3)
linkshape([0 0],[3 4],2)
linkshape([3 4],[13 4],1)
linkshape([13 4],[10 0],3)


請用help patch指令,查詢patch指令的用法,如何更改linkshape函數中之畫圖之顏色?

2.4 動畫之製作例

為配合機動學的講授,使用MATLAB的繪圖功能,可以產生物體移動的效果。前文曾討論有關座標的轉移方式,可以先將某一已設定的圖案作平移或旋轉,或者兩者合併,以達到不同的需求與目的。這些座標轉換指令為:

function xprime=trans4(x,delx,mod)

其中x代表全部的座標矩陣,mod則為轉換的模式,當mod=1時表示移動,其移動量依delx決定,此為一列矩陣,對應於座標數。Mod=5時為轉動,若為平面,此時delx代表轉動的角度,以度數表示。若為立體座標,則其內容應為三元素之列矩陣。

當一個動作包含有移動與轉動時,上述指令必須依功能需要呼叫兩次。最好的處理方法是先行處理純轉動座標變換,其後再作移動轉換,如此才不會因旋轉中心改變而產生意外的結果。

連桿之轉動


為取得特定連桿之外圍座標,可以將上節之linkshape函數稍作修改,使其輸出為一組可用之(x,y)座標(註:本程式未使用trans4函數之呼叫,但直接擷取其內容):

function [x,y]=links(A,B,d)
% Find coordinates of a link
% Inputs:
% A,B:Initial & final coordinates of link
% d:thickness of link
% Output:[x,y]:Coordinates of the link
% Example: links([0 0],[5,5])
if nargin==2,d=1;end;
AB=(B(1)+j*B(2))-(A(1)+j*A(2));
D=abs(AB);th=angle(AB);
t=linspace(pi/2,2.5*pi,20);
Cout=(d/2)*exp(j*t');Cin=Cout/2;
P=[0;Cin;Cout(1:10);D+Cout(11:20);D+Cin;D+Cout(20);Cout(1)];
xx=real(P);yy=imag(P);
x=xx*cos(th)-yy*sin(th)+A(1);
y=xx*sin(th)+yy*cos(th)+A(2);


運動之過程



利用MATLAB繪製動畫有兩種方法,其一是先儲存一定數格的圖格,然後再按順序播放,成為連續的電影;其二是在螢幕上連續繪圖及擦拭,以產生連續的動作變化。圖面內容若相當複雜,且有色彩搭配時,以採用第一種方式為宜,如此可以產生一個接近實體之連續影像。這些影像可以事先輸入或繪製,播放時只要將其一幕幕放映即可。這種方式可能會產生閃耀不穩,且所佔的記憶體也較大。

第二種技巧是利用電腦的快速繪圖功能,將影像繪製完成後,再擦去,使其產生視覺暫留的印象。利用MATLAB所提供的模式可以選擇不同的呈現方式。這種方式速度快,但正確性較差。在動力或機動學方面,可以示範組件的動作,故也相當理想。

擦拭模式


MATLAB 指令中,簡單的圖可以使用擦拭重畫法以產生動畫。產生動畫之原理是將某一物體之座標改變之後,擦去前面所繪的圖像,重新依新座標繪製一次,如此連續不斷,產生一系列的動作畫面。這個動作須令'erasemode'的參數值等於'xor'才能完成。典型的畫法是畫出該物體後,然後在迴圈中,不斷地些微改變其位置座標,然後畫出新的畫面。其座標分別以x,y,z表示。在指令中亦可直接設定'erasemode'之值達到程式控制的目的。'erasemode'的參數有三種選擇:

  • none - MATLAB 會在繪出新圖案前不將舊圖清除。
  • background - MATLAB 會用背景顏色將舊圖重新繪製一次。故此種模式除將舊圖清除外,其底下原有的繪製物如格線等亦被清除。
  • xor – 此模式僅擦拭物體部份,最常用於動畫。

這三種模式是MATLAB繪圖指令中之執行速度最快者,但仍然視圖像的細節及運算的時間而定。若變化太過快速,可利用pause指令來延遲經歷之時間。在機動學中之動作中,本節將以此功能配合各項分析結果產生動畫,使同學瞭解其中之變化過程。

程式內容


本程式呼叫links函數,以得到單桿之外形之座標點,然後依與時間相關之迴轉角度delt順序旋轉。擦拭模式可以在程式中依下述的方法在繪製時就先設定:

h1=line(x,y,'erasemode','xor','color','r','linewidth',2);

指令中,h1為其握把,以此認定所需改變的線圖。注意此時之'erasemode' 參數值設定為 'xor',表示使用擦拭模式,亦即在下一次繪製新圖時,會將上次繪製之舊圖塗去,以觀察連續變動之影像。在每次繪製前必須將新的座標指向該握把,可利用此指令為之:

 set(h1,'xdata',x2,'ydata',y2);

採用set指令與直接下 line有點不同, line指令下達後,繪圖動作立即進行,但set指令僅先設定所要的值在緩衝器上,並不立即執行。因此你可以執行set好幾次,等到滿意之後才一次執行。執行繪圖的動作須配合drawnow之下達,才能一次繪出。下面的程式中,係先執行drawnow,表示先執行第一次準備之資料,但這只是程式的應用技巧,到底drawnow事先下或後下,依使用情況而定,一般並不影響結果。故實際上應用上也可置於執行set指令之後。

function link_rot1(r,d,v)
%link_rot1.m will call links.m
%Rotating a link
%Example: link_rot1(10,3,50)
%Author:DSFon, BIME,NTU. Date:Jan. 24, 2007
clf;
if nargin==0,r=10;d=1;v=50;end
[x,y]=links([0 0],[r,0],d);
delt=pi/120; %delaying time for display
axis([-r r -r r]*1.2);
axis image;axis off;
t=0:2*pi/50:2*pi;
h0=line(r*cos(t),r*sin(t),'color','b','linestyle',':');
h1=line(x,y,'erasemode','xor','color','r','linewidth',2);
x1=get(h1,'xdata');y1=get(h1,'ydata');
title('Press Ctl-C to stop');
theta1=0;s1=delt;
while 1,
drawnow;
pause(1/v);
theta1=theta1+s1;
x2=x1*cos(theta1)-y1*sin(theta1);
y2=x1*sin(theta1)+y1*cos(theta1);
set(h1,'xdata',x2,'ydata',y2);
if theta1>2*pi,theta1=theta1-2*pi;end;
end



執行結果




按此觀賞動畫:

2.6 機器人的軸節

利用Matlab可以模擬工業機器人軸節之運動情形。下面為一個執行例,以 robot IRB 140 (ABB) 為模擬對象,可以看到其軸節間之運動情形。



就目前所學之平面二軸之迴轉,亦可仿不同軸節之機器人動作。程式link_robot函數可以依輸入之桿長及對應角度與各桿之迴轉速度繪出其連續性之運動。本程式並呼叫linkxy求得各桿中間之座標,然後進行繪製。其程式內容如下:


function link_robot(lens,angle,omega,w)
%link_robot.m will call linkspace.m
%draw connecting links as a connected mechanism.
%Input:lens:lengths of links
% angle:link angles w/t the former link, degs
% omega:angular velocity, rad/s
% w:width of links
% time:[stop delt]
%Example:
% link_robot([5 3 4 6],[30 60 90 145],2:5)
%Author:DSFon, BIME,NTU. Date:Jan. 25, 2007
if nargin<4,w=1;end
if nargin<3,omega=1;end;
lens=lens(:);angle=angle(:);omega=omega(:);
if length(omega)==1,
omega=ones(size(lens))*omega;
end
t=0;nn=length(lens);clf;
for i=1:nn,
h(i)=line('xdata',[],'ydata',[],'erasemode','xor');
end
mm=sum(lens)-min(lens);
axis([-mm mm -mm mm]);axis equal;axis off;
title('Hit ctr-C to stop');
while 1
th=cumsum(angle+omega*t)*pi/180;
x=[0;cumsum(lens.*cos(th))];
y=[0;cumsum(lens.*sin(th))];
for i=1:nn
[xi,yi]=linkxy([x(i) y(i)],[x(i+1) y(i+1)],w);
set(h(i),'xdata',xi,'ydata',yi);
end
drawnow;
pause(0.1)
t=t+1;if t>1000,t=0;end
end

function [x,y]=linkxy(A,B,d)
% Draw a link
% Inputs:
% A,B:Initial & final coordinates of link
% d:thickness of link
% Example: linkshape([0 0],[5,5])
if nargin==2,d=1;end;
d=abs(d);
AB=(B(1)+j*B(2))-(A(1)+j*A(2));
D=abs(AB);th=angle(AB);
t=linspace(pi/2,2.5*pi,20);
Cout=max(d/2,0.2)*exp(j*t');Cin=Cout/2;
if d>0,
P=[0;Cin;Cout(1:10);D+Cout(11:20);D+Cin;D+Cout(20);Cout(1)];
else
P=[Cin;0;D;D+Cin];
end
xx=real(P);yy=imag(P);
x=xx*cos(th)-yy*sin(th)+A(1);
y=xx*sin(th)+yy*cos(th)+A(2);

執行上述程式可得到下面影像之動作:

>> link_robot([5 3 4 6],[30 60 90 145],2:5)