4-1%20%B0%F2%A5%BB%AA%BA%A4T%BA%FB%C3%B8%B9%CF%AB%FC%A5O

mesh 和 surf 是三度空間立體繪圖的基本指令,mesh 可畫出立體的「網狀圖」(Mesh Plots),surf 則可畫出立體的「曲面圖」(Surface Plots),兩者產生的圖形都會依高度而有不同顏色。下列範例畫出一個二維矩陣的立體網狀圖:

Example 1: 04-三維立體繪圖/plotxyz001.mz = [0 2 1; 3 2 4; 4 4 4; 7 6 8]; mesh(z); xlabel('X 軸 = column index'); % X 軸的說明文字 ylabel('Y 軸 = row index'); % Y 軸的說明文字 %colormap(zeros(1,3)); % 以黑色呈現

在上述範例中,X 軸對應到矩陣 z 的直行索引,Y 軸則對應到橫列索引,換句話說,在上述圖形中,當 x = j 且 y = i 時,所對應的高度是 z(i, j),可以驗證如下:

Example 2: 04-三維立體繪圖/plotxyz002.mz = [0 2 1; 3 2 4; 4 4 4; 7 6 8]; mesh(z); xlabel('X 軸 = column index'); % X 軸的說明文字 ylabel('Y 軸 = row index'); % Y 軸的說明文字 for i=1:size(z,1) for j=1:size(z,2) h=text(j, i, z(i,j), num2str(z(i, j))); % 標示曲面高度 set(h, 'hori', 'center', 'vertical', 'bottom', 'color', 'r'); % 改變位置及顏色 end end %colormap(zeros(1,3)); % 以黑色呈現

若要將與曲面對應的 x 座標和 y 座標都一併畫出來,還是可以使用 mesh 指令,例如我們可以畫出曲面 $z=xy$ 在 $x \in [3, 6]$ 及 $y \in [5, 9]$ 的網狀圖:

Example 3: 04-三維立體繪圖/plotxyz011.mx = 3:6; y = 5:9; [xx, yy] = meshgrid(x, y); % xx 和 yy 都是矩陣 zz = xx.*yy; % 計算函數值 zz,也是矩陣 subplot(2,2,1); mesh(xx); title('xx'); axis tight subplot(2,2,2); mesh(yy); title('yy'); axis tight subplot(2,2,3); mesh(xx, yy, zz); title('zz 對 xx 及 yy 作圖'); axis tight

在上述範例中,meshgrid 的作用是產生 x 及 y (均為向量) 為基準的格子點 (Grid Points),其輸出為 xx 及 yy(均為矩陣),分別代表格子點的 x 座標及 y 座標。

在下列範例中,我們使用 linspace 來產生較密集的資料,以便畫出由函數 $z=xe^{-x^2-y^2}$ 形成的立體網狀圖:

Example 4: 04-三維立體繪圖/plotxyz01.mx = linspace(-2, 2, 25); % 在 x 軸 [-2,2] 之間取 25 點 y = linspace(-2, 2, 25); % 在 y 軸 [-2,2] 之間取 25 點 [xx, yy] = meshgrid(x, y); % xx 和 yy 都是 25×25 的矩陣 zz = xx.*exp(-xx.^2-yy.^2); % 計算函數值,zz 也是 25×25 的矩陣 mesh(xx, yy, zz); % 畫出立體網狀圖 %colormap(zeros(1,3)); % 以黑色呈現

surf 和 mesh 指令的用法類似,但產生的圖形是立體曲面圖:

Example 5: 04-三維立體繪圖/plotxyz02.mx = linspace(-2, 2, 25); % 在 x 軸 [-2,2] 之間取 25 點 y = linspace(-2, 2, 25); % 在 y 軸 [-2,2] 之間取 25 點 [xx,yy] = meshgrid(x, y); % xx 和 yy 都是 25×25 的矩陣 zz = xx.*exp(-xx.^2-yy.^2); % zz 也是 25×2 的矩陣 surf(xx, yy, zz); % 畫出立體曲面圖 colormap('default') % 顏色改回預設值

為了方便測試立體繪圖,MATLAB 提供了一個 peaks 函數,可產生一個凹凸有致的曲面,包含了三個局部極大點(Local Maxima)及三個局部極小點(Local Minima),其方程式為: $$ z=3(1-x)^2e^{-x^2-(y+1)^2}-10(\frac{x}{5}-x^3-y^5)e^{-x^2-y^2}-\frac{1}{3}e^{-(x+1)^2-y^2} $$

要畫出此函數的最快方法,即是在 MATLAB 命令視窗直接鍵入 peaks,可得到下列方程式與圖形:

Example 6: 04-三維立體繪圖/peaks01.mpeaks z = 3*(1-x).^2.*exp(-(x.^2) - (y+1).^2) ... - 10*(x/5 - x.^3 - y.^5).*exp(-x.^2-y.^2) ... - 1/3*exp(-(x+1).^2 - y.^2)

我們亦可對 peaks 指令取點,再以各種不同方法進行繪圖,相關細節可由「help peaks」而查到線上支援。

meshz 指令有將曲面加上「圍裙」或「舞台」的效果:

Example 7: 04-三維立體繪圖/plotxyz03.m[x, y, z] = peaks; meshz(x,y,z); axis tight;

Hint
�� 在上例中,“axis tight”會將圖軸在 x、y、z 方向的範圍定為圖形資料在 x、y、z 方向的極大值及極小值,因此會使圖形“塞滿”整個圖軸。使用「axis([-inf, inf, -inf, inf, -inf, inf])」可以達到相同的效果。

waterfall 指令可在 x 方向或 y 方向產生水流效果:

Example 8: 04-三維立體繪圖/plotxyz04.m[x, y, z] = peaks; waterfall(x,y,z); axis tight;

meshc 可同時畫出網狀圖與「等高線」(Contours):

Example 9: 04-三維立體繪圖/plotxyz05.m[x, y, z] = peaks; meshc(x, y, z); axis tight;

surfc 可同時畫出曲面圖與等高線,而 contour、contourf、contour3 等指令則可畫出不同呈現方式的等高線,可詳見第五章「特殊圖形」的說明。

plot3 指令可畫出三度空間中的曲線:

Example 10: 04-三維立體繪圖/plotxyz06.mt = linspace(0,20*pi, 501); % 在 0 及 20*pi 中間取 501 點 plot3(t.*sin(t), t.*cos(t), t); % 畫出 tsin(t),tcos(t),t 的曲線

亦可同時畫出兩條三度空間中的曲線:

Example 11: 04-三維立體繪圖/plotxyz07.mt = linspace(0, 10*pi, 501); plot3(t.*sin(t), t.*cos(t), t, t.*sin(t), t.*cos(t), -t); % 同時畫兩條曲線

如果輸入引數是三個大小相同的矩陣 x、y、z,那麼 plot3 會依序畫出每個行向量在三度空間所對應的曲線,如下:

Example 12: 04-三維立體繪圖/plotxyz08.m[x, y] = meshgrid(-2:0.1:2); z = y.*exp(-x.^2-y.^2); plot3(x, y, z);

在上例中,所有的資料點都必需是在格子點上,MATLAB 才能根據每點的高度來作圖。如果所給的資料點不在格子點上,我們必需先用 griddata 指令來進行內插法以產生格子點,例如:

Example 13: 04-三維立體繪圖/plotxyz09.mx = 6*rand(100,1)-3; % x 為介於 [-3, 3] 的 100 點亂數 y = 6*rand(100,1)-3; % y 為介於 [-3, 3] 的 100 點亂數 z = peaks(x, y); % z 為 peaks 指令產生的 100 點輸出 [X, Y] = meshgrid(-3:0.1:3); Z = griddata(x, y, z, X, Y, 'cubic'); % 用 cubic 內差法進行內差 meshc(X, Y, Z); hold on plot3(x, y, z, '.', 'MarkerSize', 16); % 晝出 100 個取樣 hold off axis tight

其中 x、y、z 代表資料點(或取樣點),而 X、Y、Z 則代表根據資料點進行內插法所得到的格子點,以畫出上面的網狀圖。有關於曲線及曲面的內插,可參見本書姊妹作「MATLAB 程式設計:進階篇」第九章「內差法」。

以下是基本三維立體繪圖指令的列表:

類別指令說明
網狀圖 mesh, ezmesh 立體網狀圖
meshc, ezmeshc 網狀圖加上等高線
meshz 網狀圖加上“圍裙”(或“舞臺”)
曲面圖 surf, ezsurf 立體曲面圖
surfc, ezsurfc 曲面圖加上等高線
surfl 曲面圖加上光源
曲線圖 plot3, ezplot3 立體曲線圖
低階函數 surface surf 用到的低階指令
line3 plot3 用到的低階指令
等高線 contour, ezcontour 平面上的等高線
contour3 空間中的等高線
影像表示 pcolor 在二維平面中以顏色表示曲面的高度

如果我們只是要很快地檢視一個具有二個輸入的函數的圖形,就可以使用 ezmesh 或是 ezsurf 等來快速地畫出函數的曲面圖形,例如:

Example 14: 04-三維立體繪圖/plotxyz091.msubplot(2,2,1); ezmesh('sin(x)/x*sin(y)/y'); subplot(2,2,2); ezsurf('sin(x*y)/(x*y)'); subplot(2,2,3); ezmeshc('sin(x)/x*sin(y)/y'); subplot(2,2,4); ezsurfc('sin(x*y)/(x*y)');

很難想像這些簡單的函數可以產生如此複雜的曲面吧?


MATLAB程式設計:入門篇