这是我尝试模拟水面。当我使用surf()
函数时,它工作正常。但当我将其更改为bar3()
时,会发生以下错误:“矩阵尺寸必须一致,不能渲染网格”。有人可以告诉我如何解决这个问题?这是我的代码:
n=60;
i = 2:n-1;
j = 2:n-1;
H = ones(n,n);
Dropx=30; %x and y coordinate of the droplet
Dropy=30;
width=20;
r=width/2;
dt=0.1;
dx=0.3;
%%% add droplet to the surface %%%
[x,y] = ndgrid(-1.5:(2/(width/1.5-1)):1);
D = 8*exp(-5*(x.^2+y.^2));
w = size(D,1);
i2 = (Dropx-r):w+(Dropx-r)-1;
j2 = (Dropy-r):w+(Dropy-r)-1;
H(i2,j2) = H(i2,j2) + D;
oldH=H;
newH=H;
h=surf(newH); % cannot change this to bar3
axis([1 n 1 n -2 8]);
k=0.2; %damping constant
c=2; %wave speed
while 1==1
newH(i,j)=H(i,j)+(1-k*dt)*(H(i,j)-oldH(i,j))-...
dt^2*c^2/dx^2*((4*H(i,j)-H(i+1,j)-H(i-1,j)-H(i,j+1)-H(i,j-1))...
+0.4*(4*H(i,j)-H(i+1,j+1)-H(i+1,j-1)-H(i-1,j+1)-H(i-1,j-1)));
set(h,'Zdata', newH(i,j));
oldH=H;
H=newH;
pause(0.05);
end
答案 0 :(得分:0)
问题在于你处理绘图的方式。
h=bar3(newH);
绘制数据并将句柄存储到h中的补丁图形对象。当您写下以下内容时:
set(h,'Zdata', newH(i,j));
你假设句柄'Zdata'是一个60x60阵列,而不是bar3的情况。只需写下
output = get(h,'Zdata')
看到了。它需要更多的数据处理才能这样做,但这似乎很乏味。
我建议一个简单的解决方案,只需在每个时间步骤重新绘制:
oldH=H;
newH=H;
h=bar3(newH);
axis([1 n 1 n -2 8]);
k=0.2; %damping constant
c=2; %wave speed
while 1==1
newH(i,j)=H(i,j)+(1-k*dt)*(H(i,j)-oldH(i,j))-...
dt^2*c^2/dx^2*((4*H(i,j)-H(i+1,j)-H(i-1,j)-H(i,j+1)-H(i,j-1))...
+0.4*(4*H(i,j)-H(i+1,j+1)-H(i+1,j-1)-H(i-1,j+1)-H(i-1,j-1)));
h=bar3(newH);
axis([1 n 1 n -2 8]);
oldH=H;
H=newH;
pause(0.05);
end
答案 1 :(得分:0)
正如大卫所说,问题在于bar3
会将原始数据矩阵转换为特殊的ZData
。这个新的补丁是一个单元格数组,长度为n
(代码中为60),每个都是一个大小为[n*6,4]
的数组。因此,您无法直接将新矩阵分配给ZData
。
除了每次重新创建情节外,还有一种解决方案。基本上,它直接修改ZData
。您可以直接按元素Zdata
修改元素。为此,请尝试以下代码,而不是调用set(h,'Zdata', newH(i,j));
:
for ih=j
set(h(ih), 'ZData', kron(newH(i,ih),[nan 0 0 nan;0,1,1,0;0,1,1,0;nan 0 0 nan;nan 0 0 nan;nan nan nan nan]));
end
h
是情节的处理;在bar3
的情况下,其长度为n
,即矩阵的第一维。因此,对于每个条形列,您可以根据其格式设置ZData
。矩阵的每个元素V都转换为该矩阵:
NaN 0 0 NaN
0 V V 0
0 V V 0
NaN 0 0 NaN
NaN 0 0 NaN
NaN NaN NaN NaN
因此,为了构建每列的完整ZData
,可以使用更新矩阵的列和此原子矩阵调用函数kron
。
这不是很快;在我的电脑上,显示器不时落后,但它比每次重建条形图要快。使用surf
会更快,因为要绘制的补丁较少。