结合Matlab脚本 [英] Combining matlab Scripts

查看:95
本文介绍了结合Matlab脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在MATLAB中创建用户交互式动画,其中形状在屏幕上平移和旋转,并且用户必须单击它,并且一旦单击空白,程序就会退出.我已经编写了动画和单击脚本,但是不确定如何将它们组合在一起.我已经在下面发布了每个脚本.任何帮助将不胜感激.

I am trying to create a user interactive animation in MATLAB where a shape translates and rotates across the screen and the user has to click on it and as soon as they click on white space, the program exits. I have the animation and the clicking script written but I am unsure how to combine them. I have posted each script below. Any help would be greatly appreciated.

clear all; close all; clc
nSides =4;
%Polar points
r=1;
theta = pi/nSides * (1:2:2*nSides-1);

%Cartesisn points
x0 = r * cos(theta);
y0 = r * sin(theta);
nFrames = 100;
xx = linspace(0,10, nFrames);
yy = xx;

rr = linspace(0, 2*pi, nFrames);

for i = 1:nFrames

rX = [cos(rr(i)), -sin(rr(i))];
rY = [sin(rr(i)), cos(rr(i))];

x1 = rX * [x0; y0];
y1 = rY * [x0; y0];

y=fill(x1 + xx(i), y1 + yy(i), 'b');
xlim([0,10]); ylim([0,10]);
hold on;
pause(0.000000003);
delete(y);

end



xv = [ -3 3 3 -3]; %// x coords of polygon vertices. Arbitrary number
yv = [-5 -5 7 7]; %// y coords of polygon vertices. Same number as for x
fill(xv,yv,'b') %// draw polygon
axis([-10 10 -10 10])
[xp, yp] = ginput(1); %// get point coordinates
inside = inpolygon(xp,yp,xv,yv); %// is it inside?

while inside
fprintf('Inside\n')
[xp, yp] = ginput(1);
inside = inpolygon(xp,yp,xv,yv);
end
fprintf('Outside\n')

错误:

Error using inpolygon (line 66)
Polygon must be defined by vectors (XV, YV).

Error in mouseDownCallback (line 20)
    if
    inpolygon(coordinates(1),coordinates(2),xVertices,yVertices) 
Error using pause
Error while evaluating figure WindowButtonDownFcn

Error using inpolygon (line 66)
Polygon must be defined by vectors (XV, YV).

Error in mouseDownCallback (line 20)
    if
    inpolygon(coordinates(1),coordinates(2),xVertices,yVertices) 
Error using pause
Error while evaluating figure WindowButtonDownFcn

Error using delete
Invalid or deleted object.

Error in movingPolygon (line 40)
delete(y);

推荐答案

组合脚本的另一种方法是在显示多边形的图形上注册一个回调,以便每次用户在鼠标轴上单击时触发该回调.数字.它相对简单明了,只需要很少的代码行,尽管它确实使用了可能会或可能不会成为问题的全局变量. (替代方法是创建一个类来管理图形和回调,并消除对全局变量的需要.)

An alternative to combining scripts is to register a callback with the figure that is displaying the polygon so that the callback fires every time the user clicks within the axes of the figure. It is relatively straightforward and requires very few lines of code, though does make use of global variables which may or may not be an issue. (The alternative to this is to create a class to manage the figure and callbacks, and removes the need for global variables.)

为使事情简单一些,请将您的第一个脚本更改为一个函数,该函数将代码包装为

To make things a little simpler, change your first script into a function, which wraps the code as

function movingPolygon
    % your code
end

函数名称可以与脚本名称相同.我们这样做是为了可以将回调函数添加到该文件.在您的主函数中,在清除命令之后声明三个全局变量

The function name can be the same as the script name. We do this so that we can add the callback function to this file. In your main function, declare three global variables after the clear commands

clear all; close all; clc

global gUserHitPolygon;   % indicates whether the user has hit the polygon or not
global gCurrentXVertices; % the x-vertices of the moving polygon
global gCurrentYVertices; % the y-vertices of the moving polygon

默认gUserHitPolygon为true,因为我们希望多边形一直移动到用户点击空白

Default gUserHitPolygon to true since we want the polygon to move until the user hits the whitespace

gUserHitPolygon = true;

for循环中更新多边形位置,只需将x和y顶点(在fill中使用)保存到其余两个全局变量.因此,在i的每次迭代中,都会更新这两个全局变量.

In the for loop to update the polygon position, just save the x- and y-vertices (used in fill) to the remaining two global variables. So on each iteration of i, these two global variables are updated.

现在,我们将继续移动多边形,直到用户未命中为止,因此,在暂停后,for循环中的最后一条语句应该是检查用户是否已命中多边形或错过了多边形

Now we continue moving the polygon until the user misses hit, so the last statement in your for loop, just after the pause, should be to check to see if the user has hit the polygon or missed it

if ~gUserHitPolygon
    clear GLOBAL gUserHitPolygon gCurrentXVertices gCurrentYVertices;
    break;
end

在上面,我们只是清除了全局变量(因为不再需要)并打破了for循环.

In the above, we just clear the global variables (since no longer needed) and break out of the for loop.

除了定义回调之外,剩下要做的就是注册鼠标按下事件.在进入for循环之前,创建一个图形并将其注册为该事件

The only thing left to do, besides defining the callback, is to register for the mouse button down events. Just prior to entering the for loop, create a figure and register it for this event

h = figure;
set(h,'WindowButtonDownFcn',   @mouseDownCallback);

就这样-图形现在将响应鼠标按下事件.在同一文件中定义的回调类似于第二个脚本

That's it - the figure will now respond to mouse button down events. The callback, defined in the same file, resembles your second script

% Callback for the mouse button down event.
function mouseDownCallback(~,~)

    global gUserHitPolygon;
    global gCurrentXVertices;
    global gCurrentYVertices;

    % save to local variables in case these globals are cleared (this is the
    % "danger" of using globals - not "thread-safe")
    xVertices = gCurrentXVertices;
    yVertices = gCurrentYVertices;

    % if we have valid (so non-empty) sets of x- and y-vertices then...
    if ~isempty(xVertices) && ~isempty(yVertices)

        % get the coordinate on the current axis
        coord = get(gca,'CurrentPoint');
        coord = coord(1,1:2);

        % if the coordinate is not in the polygon, then change the
        % flag
        if ~inpolygon(coord(1),coord(2),xVertices,yVertices)
           gUserHitPolygon = false;
        end
    end
end

就是这样.尝试以上操作,看看会发生什么.

And that is it. Try the above and see what happens.

这篇关于结合Matlab脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆