如何在 MATLAB 中更新冲浪图?
How can I update a surf plot in MATLAB?
我尝试使用一条线来模拟机器人运动,'o'
,作为机器人。我使用 set
更新它的动作。但是我在更新机器人视角的新位置和角度时遇到了问题。我使用 surf
作为机器人视角,因为我想显示颜色渐变。现在我必须删除 surf
情节,并且每次都重新绘制。
如何更新图形,而不是每次都完全重绘?
这是我的代码:
classdef Robot6<handle
properties
velocity = 0;
position = [0 0];
angle=0;
end
methods
function Runn(obj)
set( gcf,'WindowKeyPressFcn', @keyboard_down,'CloseRequestFcn', @close_window, 'WindowKeyReleaseFcn', @keyboard_up)
set( gca,'color', 'white','xlim', [-100, 100],'ylim', [-100, 100])
robot=line(obj.position(1), obj.position(2),'marker','o');
hold(gca,'on')
program_on = 1;
while program_on
userdataStore=[obj.velocity obj.angle obj.position]
%pause(0.001);
vel = [userdataStore(1)*cosd(userdataStore(2)),userdataStore(1)*sind(userdataStore(2))];
pos = userdataStore(3:4);
new_position = pos + vel;
if (abs(new_position(1)) > 100 || abs(new_position(2)) > 100)
new_position = pos;
end
obj.position = new_position;
set(robot, 'XData', new_position(1), 'YData', new_position(2));
%set(orient,'XData', new_position(1)+2*cos(userdataStore(2)), 'YData', new_position(2)+2*sin(userdataStore(2)));
%delete(orient)
x=[new_position(1) new_position(1)+10*cosd(userdataStore(2))+(10*tand(35)*cosd(90-userdataStore(2))) new_position(1)+10*cosd(userdataStore(2))-(10*tand(35)*cosd(90-userdataStore(2)))];
y=[new_position(2) new_position(2)+10*sind(userdataStore(2))-10*tand(35)*sind(90-userdataStore(2)) new_position(2)+10*sind(userdataStore(2))+10*tand(35)*sind(90-userdataStore(2))];
z=[100 0 0];
xv = linspace(min(x), max(x), 1000);
yv = linspace(min(y), max(y), 1000);
[X,Y] = meshgrid(xv, yv);
Z = griddata(x,y,z,X,Y);
figure(1)
orient=surf(X, Y, Z);
grid off
%set(gca, 'ZLim',[0 500])
shading interp
colormap(jet(80))
view(2)
pause(1)
delete(orient)
pause(0.00000000001)
end
delete(gcf);
function close_window(~,~)
program_on = 0;
end
function keyboard_down(~, event)
switch event.Key
case 'downarrow'
obj.velocity = -5;
case 'uparrow'
obj.velocity = 5;
case 'leftarrow'
obj.angle = obj.angle + 6;
case 'rightarrow'
obj.angle = obj.angle - 6;
otherwise
disp('unknown key');
end
end
function keyboard_up(~,~)
obj.velocity = 0;
end
end
end
end
您可以像更新 robot
图形对象一样进行操作。在初始化 robot
之后初始化一个空的 surf
对象,然后在 while 循环中只用 set
.
更新表面
所以对于你的代码,就在你的行下面:
robot=line(obj.position(1), obj.position(2),'marker','o');
hold(gca,'on')
声明空表面对象(它会存在但此时不会出现,因为它没有数据点):
orient = surf([],[],[]) ;
然后在主 while 循环中,替换行:
orient=surf(X, Y, Z);
这个:
set(orient,'XData',X,'YData',Y,'ZData',Z)
这回答了关于如何更新 surf
图而不是每次都重新绘制的主要问题。请注意,现在您并不是在每个循环中都重新创建绘图,许多 axes
和 figure
属性不会在每次更新时重新计算,因此您也可以采用所有这些行:
grid off
%set(gca, 'ZLim',[0 500])
shading interp
colormap(jet(80))
view(2)
脱离主循环并将它们放置在表面创建之后。这些属性将保持不变,不需要在每次循环迭代时再次设置。
我尝试使用一条线来模拟机器人运动,'o'
,作为机器人。我使用 set
更新它的动作。但是我在更新机器人视角的新位置和角度时遇到了问题。我使用 surf
作为机器人视角,因为我想显示颜色渐变。现在我必须删除 surf
情节,并且每次都重新绘制。
如何更新图形,而不是每次都完全重绘?
这是我的代码:
classdef Robot6<handle
properties
velocity = 0;
position = [0 0];
angle=0;
end
methods
function Runn(obj)
set( gcf,'WindowKeyPressFcn', @keyboard_down,'CloseRequestFcn', @close_window, 'WindowKeyReleaseFcn', @keyboard_up)
set( gca,'color', 'white','xlim', [-100, 100],'ylim', [-100, 100])
robot=line(obj.position(1), obj.position(2),'marker','o');
hold(gca,'on')
program_on = 1;
while program_on
userdataStore=[obj.velocity obj.angle obj.position]
%pause(0.001);
vel = [userdataStore(1)*cosd(userdataStore(2)),userdataStore(1)*sind(userdataStore(2))];
pos = userdataStore(3:4);
new_position = pos + vel;
if (abs(new_position(1)) > 100 || abs(new_position(2)) > 100)
new_position = pos;
end
obj.position = new_position;
set(robot, 'XData', new_position(1), 'YData', new_position(2));
%set(orient,'XData', new_position(1)+2*cos(userdataStore(2)), 'YData', new_position(2)+2*sin(userdataStore(2)));
%delete(orient)
x=[new_position(1) new_position(1)+10*cosd(userdataStore(2))+(10*tand(35)*cosd(90-userdataStore(2))) new_position(1)+10*cosd(userdataStore(2))-(10*tand(35)*cosd(90-userdataStore(2)))];
y=[new_position(2) new_position(2)+10*sind(userdataStore(2))-10*tand(35)*sind(90-userdataStore(2)) new_position(2)+10*sind(userdataStore(2))+10*tand(35)*sind(90-userdataStore(2))];
z=[100 0 0];
xv = linspace(min(x), max(x), 1000);
yv = linspace(min(y), max(y), 1000);
[X,Y] = meshgrid(xv, yv);
Z = griddata(x,y,z,X,Y);
figure(1)
orient=surf(X, Y, Z);
grid off
%set(gca, 'ZLim',[0 500])
shading interp
colormap(jet(80))
view(2)
pause(1)
delete(orient)
pause(0.00000000001)
end
delete(gcf);
function close_window(~,~)
program_on = 0;
end
function keyboard_down(~, event)
switch event.Key
case 'downarrow'
obj.velocity = -5;
case 'uparrow'
obj.velocity = 5;
case 'leftarrow'
obj.angle = obj.angle + 6;
case 'rightarrow'
obj.angle = obj.angle - 6;
otherwise
disp('unknown key');
end
end
function keyboard_up(~,~)
obj.velocity = 0;
end
end
end
end
您可以像更新 robot
图形对象一样进行操作。在初始化 robot
之后初始化一个空的 surf
对象,然后在 while 循环中只用 set
.
所以对于你的代码,就在你的行下面:
robot=line(obj.position(1), obj.position(2),'marker','o');
hold(gca,'on')
声明空表面对象(它会存在但此时不会出现,因为它没有数据点):
orient = surf([],[],[]) ;
然后在主 while 循环中,替换行:
orient=surf(X, Y, Z);
这个:
set(orient,'XData',X,'YData',Y,'ZData',Z)
这回答了关于如何更新 surf
图而不是每次都重新绘制的主要问题。请注意,现在您并不是在每个循环中都重新创建绘图,许多 axes
和 figure
属性不会在每次更新时重新计算,因此您也可以采用所有这些行:
grid off
%set(gca, 'ZLim',[0 500])
shading interp
colormap(jet(80))
view(2)
脱离主循环并将它们放置在表面创建之后。这些属性将保持不变,不需要在每次循环迭代时再次设置。