gpt4 book ai didi

matlab - 通过按向左和向右箭头键为 MATLAB 图制作动画

转载 作者:太空宇宙 更新时间:2023-11-03 20:24:01 25 4
gpt4 key购买 nike

我正在尝试使用左右箭头键更改球体的半径,绘制在 MATLAB 图形中。例如,按向右箭头,半径值增加 1,然后用更新后的半径绘制新球体。同样,按向左箭头键将半径减小一,然后绘制一个较小的球体。但是,我希望将此更改限制在 1 和 rmax 之间。

阅读 this post 后,我对如何处理有了一些想法但它仍然不是我想要的。因此,我使用了两个全局变量来完成此任务,以便通过引用 KeyPressFcn 以某种方式传递信息,以便在按下某个键时 KeyPressFcn 知道这些限制是什么。在下面的示例中,代码确实将半径增加和减少了一个,但它并没有限制点击左右箭头后半径在指定范围内的变化。

有没有更好的方法来解决这个问题?如何将半径值及其限制传递给 KeyPressFcn?我想让 KeyPressFcn 知道按下左右箭头时它可以改变半径多少。

function animateme()

fig_h = figure;
set(fig_h,'KeyPressFcn', @key_pressed_fcn);

global r rmax

p0 = [0 0 0];
[x,y,z] = sphere;

rmax = 10;
r = 1;

while 1==1

h = surf(x*r+p0(1), y*r+p0(2), z*r+p0(3));
set(h, 'FaceAlpha', 0.5, 'FaceColor', rand([1 3]))
axis equal;

pause

end



function key_pressed_fcn(fig_obj, eventDat)

global r rmax

if strcmpi(eventDat.Key, 'rightarrow')
r = r + 1;
if r < 1
r = 1;
end
elseif strcmpi(eventDat.Key, 'leftarrow')
r = r - 1;
if r > rmax
r = rmax;
end
end
disp(r)

最佳答案

首先,不要使用全局变量,因为(几乎)总是有更好的方法来完成同样的事情。

下面是一个使用嵌套函数的示例,它可以自动访问父函数工作区内的变量。

function animateme()
fig = figure();
hax = axes('Parent', fig);
set(fig, 'KeyPressFcn', @keypress)

p0 = [0,0,0];
[x,y,z] = sphere();

% Specify limits here which are accessible to nested functions
rmax = 10;
r = 1;

h = surf(x,y,z, 'Parent', hax);

% Subfunction for re-plotting the data
% This prevents you from needing a while loop
function redraw()
set(h, 'XData', x * r + p0(1), ...
'YData', y * r + p0(2), ...)
'ZData', z * r + p0(3));

set(h, 'FaceAlpha', 0.5, ...
'FaceColor', rand([1 3]))

axis(hax, 'equal')
drawnow
end

% Go ahead and do the first redraw
redraw();

% Callback to process keypress events
function keypress(~, evnt)
switch lower(evnt.Key)
case 'rightarrow'
r = min(r + 1, rmax);
case 'leftarrow'
r = max(1, r - 1);
otherwise
return
end

% Always do a redraw
redraw();
end
end

另一种选择是使用 UserData 字段将 r 的当前值存储在图形对象本身中。所以你可以把它放在 surf 图中。这实际上是我的首选方法,因为这样你的回调函数就可以存在于任何地方,并且仍然可以访问它需要的数据。

function animateme()

fig = figure();

% Data to store for plotting
data.p = [0,0,0];
data.r = 1;
data.rmax = 10;

% Create a blank surface for starters
h = surf(nan(2), nan(2), nan(2));
set(h, 'UserData', data);

% Update the display of the surface
redraw(h);

% Set the callback and pass the surf handle
set(fig, 'KeyPressFcn', @(fig, evnt)keypress(h, evnt))
end

function redraw(h)

% Get the stored data from the graphics object
userdata = get(h, 'Userdata');

[x,y,z] = sphere();

set(h, 'XData', x * userdata.r + userdata.p(1), ...
'YData', y * userdata.r + userdata.p(2), ...
'ZData', z * userdata.r + userdata.p(3));

set(h, 'FaceAlpha', 0.5, ...
'FaceColor', rand([1 3]))

axis equal
drawnow;
end

function keypress(h, evnt)

% Get the stored data
userdata = get(h, 'Userdata');

switch lower(evnt.Key)
case 'rightarrow'
userdata.r = min(userdata.r + 1, userdata.rmax);
case 'leftarrow'
userdata.r = max(1, userdata.r - 1);
otherwise
return;
end

% Update the stored value
set(h, 'UserData', userdata);

redraw(h);
end

关于matlab - 通过按向左和向右箭头键为 MATLAB 图制作动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35779275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com