结合matlab脚本

时间:2014-06-01 21:33:54

标签: matlab

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

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);

1 个答案:

答案 0 :(得分:1)

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

为了使事情变得更简单,将第一个脚本更改为一个函数,将代码包装为

function movingPolygon
    % your code
end

函数名称可以与脚本名称相同。我们这样做,以便我们可以将回调函数添加到此文件。在main函数中,在clear命令

之后声明三个全局变量
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,因为我们希望多边形移动直到用户点击空白

gUserHitPolygon = true;

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

现在我们继续移动多边形,直到用户未命中,所以for循环中的最后一个语句,就在暂停之后,应检查用户是否已击中多边形或错过了多边形< / p>

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

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

除了定义回调之外,唯一要做的就是注册鼠标按钮事件。在进入for循环之前,创建一个数字并为此事件注册

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

它就是 - 现在这个数字将响应鼠标按钮事件。在同一文件中定义的回调类似于第二个脚本

% 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

就是这样。试试上面的内容,看看会发生什么。