ANS 5-1:
5-1-1,5-1-2:
body function的程式碼如下:(包含了手臂跟手掌的座標矩陣在裡面了)
%宣告函數
function body(L1,L2,L3,theta1,theta2,theta3)
%L1=10;
a=2*L1-1;
%宣告手臂的座標矩陣為兩倍手臂長的組數
arm1=zeros(a,2);
%開始輸入手臂的座標
for y1=1:1:a
%當手臂右半部y值<L1值時,對應的x為((1+4*y1).^0.5)/3-0.3;
if(y1<L1-1)
arm1(y1,2)=y1;
arm1(y1,1)=((1+4*y1).^0.5)/3-0.3;
end
%但第一組座標仍須固定在原點
if(y1==1)
arm1(y1,2)=0;
arm1(y1,1)=0;
end
%此項為修正圖形用最靠近手臂的點要做些許修正圖形較好看
if(y1==L1-1)
arm1(y1,2)=L1-0.2;
arm1(y1,1)=arm1(y1-1,1)-0.2;
end
%當Y為L長時,手臂寬度=0
if(y1==L1)
arm1(y1,2)=y1;
arm1(y1,1)=0;
end
%左半部和右半部對稱,圖形只有x差一個負號
if(y1>L1)
%圖形第二項也要做修正
arm1(2,2)=0.5;
arm1(2,1)=arm1(3,1)-0.1;
arm1(y1,2)=arm1(a-y1+1,2);
arm1(y1,1)=-arm1(a-y1+1,1);
end
%最後圖形要回到原點
if(y1==a)
arm1(y1,2)=0;
arm1(y1,1)=0;
end
end
%對手臂做旋轉
%因為一開始不小心畫了垂直的手臂,所以只好修改一下我的轉動公式的角度,
%並且得先將手臂的上端點先下移到原點做旋轉再移回原來高度
for y1=1:1:a
Arm1(y1,1)=arm1(y1,1)*cosd(theta1-90)+(arm1(y1,2)-L1)*sind(theta1-90);
Arm1(y1,2)=-arm1(y1,1)*sind(theta1-90)+(arm1(y1,2)-L1)*cosd(theta1-90)+L1;
end;
b=2*L2-1;
%宣告手臂的座標矩陣為兩倍手臂長的組數
arm2=zeros(b,2);
%開始輸入手臂的座標
for x2=1:1:b
%當手臂上半部x值<L2值時,對應的y為((1+4*x2).^0.5)/3-0.3;
if(x2<L2-1)
arm2(x2,1)=x2;
arm2(x2,2)=((1+4*x2).^0.5)/5-0.3;
end
%但第一組座標仍須固定在原點
if(x2==1)
arm2(x2,1)=0;
arm2(x2,2)=0;
end
%此項為修正圖形用最靠近手臂的點要做些許修正圖形較好看
if(x2==L2-1)
arm2(x2,1)=L2-0.2;
arm2(x2,2)=arm2(x2-1,2)-0.2;
end
%當Y為L長時,手臂寬度=0
if(x2==L2)
arm2(x2,1)=x2;
arm2(x2,2)=0;
end
%左半部和右半部對稱,圖形只有x差一個負號
if(x2>L2)
%圖形第二項也要做修正
arm2(2,2)=arm2(3,2)-0.1;
arm2(2,1)=0.5;
arm2(x2,1)=arm2(b-x2+1,1);
arm2(x2,2)=-arm2(b-x2+1,2);
end
%最後圖形要回到原點
if(x2==b)
arm2(x2,1)=0;
arm2(x2,2)=0;
end
end
% 計算後去修正我的theta2
theta2=180-theta2+theta1;
%一開始就將下手臂畫在原點x方向
%所以先做旋轉後再把他和上手臂接在一起就可以了
for x2=1:1:b
Arm2(x2,1)=(arm2(x2,1))*cosd(theta2)+(arm2(x2,2))*sind(theta2)+Arm1(1,1);
Arm2(x2,2)=-(arm2(x2,1))*sind(theta2)+(arm2(x2,2))*cosd(theta2)+Arm1(1,2);
end;
%手掌的畫法基本上是幾乎依照各點的座標作輸入
%只有盡量去簡化圖形做成對稱的手
%才能縮短程式(但也就和事實不符和)
palm=zeros(25,2);
for i=1:1:21
palm(i,2)=2.5-0.25*(i-1);
palm(i,1)=L3./2;
end
palm(3,1)=palm(3,1)+L3/2-2;
palm(19,1)=palm(3,1);
palm(2,1)=palm(3,1)-0.3;
palm(4,1)=palm(2,1);
palm(18,1)=palm(2,1);
palm(20,1)=palm(2,1);
palm(5,1)=palm(5,1)+1;
palm(17,1)=palm(5,1);
palm(7,1)=palm(7,1)+L3./2-1;
palm(15,1)=palm(7,1);
palm(6,1)=palm(7,1)-0.3;
palm(8,1)=palm(6,1);
palm(16,1)=palm(6,1);
palm(14,1)=palm(6,1);
palm(9,1)=palm(9,1)+2;
palm(13,1)=palm(9,1);
palm(11,1)=palm(10,1)+L3./2;
palm(10,1)=palm(11,1)-0.3;
palm(12,1)=palm(10,1);
for i=22:1:24
palm(i,1)=0;
end
palm(22,2)=-1.5;
palm(24,2)=1.5;
palm(25,1)=palm(1,1);
palm(25,2)=palm(1,2);
%修正theta3以符合題目所求
theta3=theta2-theta3-180;
%一開始就將手掌畫在原點x方向
%所以先做旋轉後再把他和下手臂接在一起就可以了
for i=1:1:25;
Palm(i,1)=(palm(i,1))*cosd(theta3)+(palm(i,2))*sind(theta3)+Arm2(L2,1);
Palm(i,2)=-(palm(i,1))*sind(theta3)+(palm(i,2))*cosd(theta3)+Arm2(L2,2);
end
axis equal;
grid on;
%各部位以一筆畫完成連線
%所以要記得終點和起點為同一點
line(Arm1(:,1),Arm1(:,2));
line(Arm2(:,1),Arm2(:,2));
line(Palm(:,1),Palm(:,2));
5-1-3
圖形如下:
5-1-4
手臂的運動和手指的運動不一樣,手指的運動會受其他兩指的角度改變而被迫改變(尤其是最尖端的指節),然而手臂和手腕可以各自改變其極限的角度。本題要求變動區間分為十等分,在此我將每個theta都分做十份來改變。
然而第二題的手指因為角度會互相遷至,所以整個動畫只分做十等分。
程式碼如下:
axis equal;
for theta1=-90:(15/9):-75
for theta2=-45:(15/9):-35
for theta3=-30:20/9:-10
clf;
body(34,26,16,theta1,theta2,theta3);
pause(0.0000001);
end
end
end
ANS 5-2:
5-2-1
原題目所要分析為手掌指頭在同一「平面」上的運動狀況,所以在此試以古魯伯公式(3-3)作分析。
古魯伯公式如下:
顯而易見的
N=4
J=3
考慮f時,原來旋轉結:連結度=1 球對:連結度=3。但因為在同一平面上,所以事實上手指的球隊部分,也只能具有旋轉結的功用,所以我們可以化簡古魯伯公式如下
m=3(N-J-1)+J=3(N-1)-2J
再將N,J帶入公式,可得自由度為m=3
事實上,手指運動時,角度有所限制,所以在我的分析中,我沒有討論到手指運動的角度,事實上每個指節間的角度都有限制,以我個人來說,θ1的極限90度,θ2最多大約110度,θ3也大約只能90度。
5-2-2
此題我分做兩部份來做,先寫出一個函數FINGER,是可輸入手掌長度和角度,以後要畫出FINGER就很方便,在寫第二支程式,去跑題目所要求的繪出四根指頭(大姆指除外)所可能展示的極限位置。
(1)FINGER的部分
%宣告一函數讓使用者可以輸入手掌和三指節的角度
function FINGER(L,theta1,theta2,theta3)
%畫出代表手掌心的連桿(不含手指的部分約為整個手掌長的1/2)
linkshape([0 0],[-L/2,0],1.4);
%手指分做三節,每節約為1/6的手掌長,再做修正,使三節加起來等於1/2手掌
l=L/6;
l3=l-0.7;
l2=l-0.5,
l1=l+1.2;
%旋轉時θ2會包含一個θ1先旋轉過的部分,θ3也會包含住θ2
theta2=theta1+theta2;
theta3=theta2+theta3;
%先將三連桿都畫在原點上去做旋轉,所以y值都等於0
%事實上我們的轉動方程式+號後面的部分都不需要寫
%也因為畫在原點上,所以我們先考慮每連桿的終點
%但終點最後要平移,距離就是上一根連桿的終點離原點的距離
X02=l1*cosd(theta1)+0*sind(theta1)
Y02=-l1*sind(theta1)+0*cosd(theta1)
X12=l2*cosd(theta2)+0*sind(theta2)+X02;
Y12=-l2*sind(theta2)+0*cosd(theta2)+Y02;
X22=l3*cosd(theta3)+0*sind(theta3)+X12;
Y22=-l3*sind(theta3)+0*cosd(theta3)+Y12;
%最後畫連桿的時候,除了第一桿的起點一直固定在(0 0)
%其他連桿的始點都在上一桿的終點
linkshape([0 0],[X02,Y02],1.4)
linkshape([X02,Y02],[X12,Y12],1.4)
linkshape([X12,Y12],[X22,Y22],1.4)
(2)跑題目要求的程式
%theta1,2,3都先等於0
theta3=0;
theta2=0;
%每次都要畫面暫停後再清除畫面,使畫面變成動畫
%手指每指節的運動會互相遷至,且各有極限
for theta1=0:10:90
clf;
theta2=theta2+80/8;
%可以觀察到theta3在theta2大概等於30度左右的時候就幾乎到了極限
if theta1<30
theta3=theta3+70/3;
end;
axis ([-10 10 -5 5]);
%丟入FINGER函數畫圖
FINGER(16,theta1,theta2,theta3);
pause(1);
end
5-2-3
首先利用dyad這隻函數做變化,去改變他的輸出和輸入,即可做觀察。
(1) 將dyad程式碼中dyadata=[pp vv aa]部分,程式碼此處原為虛數的pp,vv,aa加上abs(),化為dyadata=[abs(pp) abs(vv) abs(aa)],則可將虛數化為實數。
(2) vect最後不用跑出來,所以程式最後加上「;」,而dyadata要跑出來,所以不加「;」。
function [vec,dyadata] = dyad(rho,theta,td,tdd)
theta=theta(:);rho=rho(:);
n=length(rho);
if nargin<4
tdd=zeros(size(rho));
if nargin==2
td=ones(size(rho));
end
end
if length(td)==1
td=ones(size(rho))*td;
end
if length(tdd)==1
tdd=ones(size(rho))*tdd;
end
td=td(:);
tdd=tdd(:);
d2g=pi/180;
tt=exp(i*theta*d2g);
pp=rho.*tt;
vv=i*td.*pp;
aa=-pp.*td.^2+i*pp.*tdd;
%將程式碼此處原為虛數的pp,vv,aa加上abs()
%則可將虛數化為實數
dyadata=[abs(pp) abs(vv) abs(aa)]
vect=[abs(sum(dyadata));angle(sum(dyadata))/d2g];
再來利用5-2-2的第二個程式稍做修改,就再來利用上提的第二個程式稍做修改,就可以利用上提的手指變化方式丟入dyad,輸出我們想看的位置,速度,和加速度的部分。
程式碼如下:
%theta部分如上題所陳述的做改變
theta3=0;
theta2=0;
td=0;
for theta1=0:10:90
td=td+10;
theta2=theta2+80/8;
if theta1<30
theta3=theta3+70/3;
end;
%將連桿長,也就是手指三指節的長度作設定,theta是隨手指頭動作更改的值,丟入dyad函數,td我們初始值設為0再遞增
dyad([2.2 2 2],[theta1 theta2 theta3],[td td td])
end
2007年4月10日 星期二
HW5
訂閱:
張貼留言 (Atom)
2 則留言:
做得很好
謝謝教授!^_^
張貼留言