Matlab 滑动曲线上的点

Matlab 滑动曲线上的点,matlab,Matlab,我在Matlab 2017b中尝试了以下代码: function demo() clc,close all fig=figure(); ax=axes(fig,... 'Units','Normalized',... 'Position',[0.2,0.2,0.6,0.6],... 'XGrid','on',... 'YGrid','on') slider=uicontrol(... 'Parent',fig,... 'Style','sl

我在Matlab 2017b中尝试了以下代码:

function demo()

clc,close all

fig=figure();

ax=axes(fig,...
    'Units','Normalized',...
    'Position',[0.2,0.2,0.6,0.6],...
    'XGrid','on',...
    'YGrid','on')

slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',1,...
    'Callback',@slider_callback);

x=linspace(0,10);
y=1/3*x.^2;
plot(x,y,'b-')
grid on
xlabel('x-axis')
ylabel('y-axis')
hold on
p=plot(1,1/3,'ro')
hold off

    function slider_callback(hObject,eventdata)
        x=hObject.Value;
        p.XData=x;
        p.YData=1/3*x.^2;
        drawnow
    end

end
当前,我移动滑块,只有当我释放鼠标按钮时,该点才会更新。我可以进行哪些更改,以便在拖动滑块时看到点移动

谢谢

更新:多亏了维格的评论,我能够做到这一点:

function demo()

clc,close all

fig=figure();

% initialize some parameters
xstart=4;
ystart=1/3*4^2;

ax=axes(fig,...
    'Units','Normalized',...
    'Position',[0.2,0.2,0.6,0.6],...
    'XGrid','on',...
    'YGrid','on');

slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',xstart);

addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));

x=linspace(0,10);
y=1/3*x.^2;
plot(x,y,'b-')
grid on
xlabel('x-axis')
ylabel('y-axis')
hold on
plot([-5,10],[0,0],'k-');
plot([0,0],[-5,35],'k-');
p=plot(xstart,ystart,'ro');
a1=quiver(0,0,xstart,ystart,0,...
    'LineWidth',1,...
    'Color','red');
a2=quiver(0,0,0,xstart,0,...
    'LineWidth',1,...
    'Color','red');
a3=quiver(0,0,xstart,0,0,...
    'LineWidth',1,...
    'Color','red');
d=plot([0,xstart,xstart],[ystart,ystart,0],'k--');
hold off

    function slider_callback(hObject,eventdata)
        x=hObject.Value;
        p.XData=x;
        p.YData=1/3*x.^2;
        a1.UData=x;
        a1.VData=1/3*x.^2;
        a2.VData=1/3*x.^2;
        a3.UData=x;
        d.XData=[0,x,x];
        d.YData=[1/3*x.^2,1/3*x.^2,0];
        drawnow
    end

end
这将生成此图像:

我很想听到任何进一步的建议


谢谢。

您需要添加一个侦听器,然后在创建滑块时可能会忽略回调:

slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',1);

addlistener(slider,'Value','PostSet',@(hObject, event) slider_callback(slider, event));

编辑:

你可以用。然后添加:

....
addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));

h = impoint(gca,xstart,ystart);
setColor(h,'r')
point = h;
addNewPositionCallback(h,@(h) make_constraint(h));

x=linspace(0,10);
...
并删除plot
p=plot(xstart,ystart,'ro')

滑块\u回调中
替换

p.XData=x;
p.YData=1/3*x.^2;

function make_constraint(h)
        fcn = makeConstrainToRectFcn('impoint',[0 10],[1/3*h(1).^2 1/3*h(1).^2]);
        % Enforce boundary constraint function using setPositionConstraintFcn
        setPositionConstraintFcn(point,fcn);
        a1.UData=h(1);
        a1.VData=1/3*h(1).^2;
        a2.VData=1/3*h(1).^2;
        a3.UData=h(1);
        d.XData=[0,h(1),h(1)];
        d.YData=[1/3*h(1).^2,1/3*h(1).^2,0];
        set(slider, 'Value', h(1))
        drawnow
    end
因此,总代码:

function stackover()

clc,close all

fig=figure();

% initialize some parameters
xstart=4;
ystart=1/3*4^2;

ax=axes(fig,...
    'Units','Normalized',...
    'Position',[0.2,0.2,0.6,0.6],...
    'XGrid','on',...
    'YGrid','on');


slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',xstart);

addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));

h = impoint(gca,xstart,ystart);
setColor(h,'r')
point = h;
addNewPositionCallback(h,@(h) make_constraint(h));

x=linspace(0,10);
y=1/3*x.^2;
plot(x,y,'b-')
grid on
xlabel('x-axis')
ylabel('y-axis')
hold on
plot([-5,10],[0,0],'k-');
plot([0,0],[-5,35],'k-');

a1=quiver(0,0,xstart,ystart,0,...
    'LineWidth',1,...
    'Color','red');
a2=quiver(0,0,0,xstart,0,...
    'LineWidth',1,...
    'Color','red');
a3=quiver(0,0,xstart,0,0,...
    'LineWidth',1,...
    'Color','red');
d=plot([0,xstart,xstart],[ystart,ystart,0],'k--');
hold off

    function slider_callback(hObject,eventdata)
        x=hObject.Value;
        setPosition(point, [x 1/3*x^2])
        a1.UData=x;
        a1.VData=1/3*x.^2;
        a2.VData=1/3*x.^2;
        a3.UData=x;
        d.XData=[0,x,x];
        d.YData=[1/3*x.^2,1/3*x.^2,0];
        drawnow
    end

    function make_constraint(h)
        fcn = makeConstrainToRectFcn('impoint',[0 10],[1/3*h(1).^2 1/3*h(1).^2]);
        % Enforce boundary constraint function using setPositionConstraintFcn
        setPositionConstraintFcn(point,fcn);
        a1.UData=h(1);
        a1.VData=1/3*h(1).^2;
        a2.VData=1/3*h(1).^2;
        a3.UData=h(1);
        d.XData=[0,h(1),h(1)];
        d.YData=[1/3*h(1).^2,1/3*h(1).^2,0];
        set(slider, 'Value', h(1))
        drawnow
    end

end
ps
demo()
是一个现有的MATLAB函数,因此最好选择另一个名称


编辑2:

如果无法使用
impoint
,则必须添加3个侦听器:

  • WindowButtonUpFcn
    :检测鼠标何时释放
  • WindowButtonMotionFcn
    :检测鼠标何时移动
  • 按钮downfcn
    :在单击鼠标时检测
前2个需要附加到图中:

fig=figure('WindowButtonUpFcn',@drop,'WindowButtonMotionFcn',@move);
最后一个只能附加到绘图:

p=plot(xstart,ystart,'ro','ButtonDownFcn',@click);
由于
WindowButtonUpFcn
WindowButtonMotionFcn
用于整个图形,因此在移动或释放鼠标时始终会调用它们。但我们只希望在拖动点时执行函数。为此,引入了一个变量(
拖动
)。在
单击
函数中,此变量设置为
1
,表示我们正在拖动

然后在移动鼠标时,点、抖动和滑块在
move
中更新。此处添加了一个控制单元,以确保不会将点拖出滑块的边界

释放鼠标时,
拖动
再次设置为
0

当然,当你在点上方悬停时,你会很高兴知道,如果你现在点击,你可以拖动点。为此,我们可以使用

iptSetPointerBehavior(p, pointerBehavior);
这里的
pointerBehavior
是一个包含3个函数的结构:

  • enterFcn
    :当鼠标进入对象时执行
  • exitFcn
    :当鼠标退出对象时执行
  • traverseFcn
    :当鼠标进入对象和在对象中移动时执行
我们不需要最后一个。当进入鼠标时,鼠标指针被设置为边缘带有箭头的十字,离开鼠标时,鼠标指针被转换为(常规)箭头。(有关更多信息,请参阅和)

总代码为:

function stackover()

clc,close all

fig=figure('WindowButtonUpFcn',@drop,'WindowButtonMotionFcn',@move);

% initialize some parameters
xstart=4;
ystart=1/3*4^2;

dragging = 0;

ax=axes('Units','Normalized',...
    'Position',[0.2,0.2,0.6,0.6],...
    'XGrid','on',...
    'YGrid','on');

slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',xstart);

addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));


pointerBehavior.enterFcn = @(figHandle, currentPoint) set(figHandle, 'Pointer', 'fleur');
pointerBehavior.exitFcn  = @(figHandle, currentPoint) set(figHandle, 'Pointer', 'arrow');
pointerBehavior.traverseFcn = [];



x=linspace(0,10);
y=1/3*x.^2;
plot(x,y,'b-')
grid on
xlabel('x-axis')
ylabel('y-axis')
hold on
plot([-5,10],[0,0],'k-');
plot([0,0],[-5,35],'k-');
p=plot(xstart,ystart,'ro','ButtonDownFcn',@click);

iptSetPointerBehavior(p, pointerBehavior);     % set behaviour of pointer when over p
iptPointerManager(gcf);                        % let figure know what you're doing

a1=quiver(0,0,xstart,ystart,0,...
    'LineWidth',1,...
    'Color','red');
a2=quiver(0,0,0,xstart,0,...
    'LineWidth',1,...
    'Color','red');
a3=quiver(0,0,xstart,0,0,...
    'LineWidth',1,...
    'Color','red');
d=plot([0,xstart,xstart],[ystart,ystart,0],'k--');
hold off

    function slider_callback(hObject,eventdata)
        x=hObject.Value;
        p.XData=x;
        p.YData=1/3*x.^2;
        a1.UData=x;
        a1.VData=1/3*x.^2;
        a2.VData=1/3*x.^2;
        a3.UData=x;
        d.XData=[0,x,x];
        d.YData=[1/3*x.^2,1/3*x.^2,0];
        drawnow
    end


    function click(hObject,eventdata)
        dragging = 1;
    end
    function drop(hObject,eventdata)
        dragging = 0;
    end
    function move(hObject,eventdata)
        if dragging
            mouse = ax.CurrentPoint;
            x = mouse(1,1);

            if x >= slider.Max
                x = slider.Max;
            elseif x <= slider.Min
                x = slider.Min;
            end

            p.XData=x;
            p.YData=1/3*x.^2;
            a1.UData=x;
            a1.VData=1/3*x.^2;
            a2.VData=1/3*x.^2;
            a3.UData=x;
            d.XData=[0,x,x];
            d.YData=[1/3*x.^2,1/3*x.^2,0];
            slider.Value = x;
            drawnow
        end
    end


end
函数stackover()
clc,全部关闭
图=图('WindowButtonUpFcn',@drop,'WindowButtonMotionFcn',@move);
%初始化一些参数
xstart=4;
ystart=1/3*4^2;
拖动=0;
ax=轴('单位','标准化',。。。
‘位置’,[0.2,0.2,0.6,0.6],。。。
“XGrid”、“on”、,。。。
"YGrid","on",;
滑块=uicontrol(。。。
‘父’,图,。。。
'样式','滑块',。。。
‘单位’、‘标准化’、,。。。
‘位置’,[0.2,0.9,0.6,0.05],。。。
'标签','滑块1',。。。
“Min”,0,。。。
“最多”,10,。。。
“值”,xstart);
addlistener(滑块,'Value',。。。
“PostSet',@(hObject,event)slider_回调(slider,event));
pointerBehavior.enterFcn=@(figHandle,currentPoint)集合(figHandle,'Pointer','fleur');
pointerBehavior.exitFcn=@(figHandle,currentPoint)集合(figHandle,Pointer,arrow');
pointerBehavior.traverseFcn=[];
x=linspace(0,10);
y=1/3*x.^2;
图(x,y,'b-')
网格化
xlabel('x轴')
ylabel('y轴')
等等
图([-5,10],[0,0],'k-');
图([0,0],-5,35],'k-');
p=绘图(xstart、ystart、'ro','ButtonDownFcn',@click);
iptSetPointerBehavior(p,pointerBehavior);%设置指针在p上时的行为
iptPointerManager(gcf);%让figure知道你在做什么
a1=颤动(0,0,X开始,Y开始,0,。。。
“线宽”,1,。。。
“颜色”、“红色”);
a2=颤动(0,0,0,x开始,0,。。。
“线宽”,1,。。。
“颜色”、“红色”);
a3=颤动(0,0,x开始,0,0,…),。。。
“线宽”,1,。。。
“颜色”、“红色”);
d=绘图([0,xstart,xstart],[ystart,ystart,0],'k--');
拖延
函数slider\u回调(hObject、eventdata)
x=hObject.Value;
p、 扩展数据=x;
p、 YData=1/3*x.^2;
a1.UData=x;
a1.VData=1/3*x.^2;
a2.VData=1/3*x.^2;
a3.UData=x;
d、 扩展数据=[0,x,x];
d、 YData=[1/3*x.^2,1/3*x.^2,0];
刷新屏幕
结束
函数单击(hObject、eventdata)
拖动=1;
结束
函数删除(hObject、eventdata)
拖动=0;
结束
函数移动(hObject、eventdata)
如果拖动
鼠标=ax.CurrentPoint;
x=小鼠(1,1);
如果x>=slider.Max
x=滑块最大值;

elseif x您需要添加一个侦听器,然后在创建滑块时可能会忽略回调:

slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',1);

addlistener(slider,'Value','PostSet',@(hObject, event) slider_callback(slider, event));

编辑:

你可以用。然后添加:

....
addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));

h = impoint(gca,xstart,ystart);
setColor(h,'r')
point = h;
addNewPositionCallback(h,@(h) make_constraint(h));

x=linspace(0,10);
...
并删除plot
p=plot(xstart,ystart,'ro')

滑块\u回调中
替换

p.XData=x;
p.YData=1/3*x.^2;

function make_constraint(h)
        fcn = makeConstrainToRectFcn('impoint',[0 10],[1/3*h(1).^2 1/3*h(1).^2]);
        % Enforce boundary constraint function using setPositionConstraintFcn
        setPositionConstraintFcn(point,fcn);
        a1.UData=h(1);
        a1.VData=1/3*h(1).^2;
        a2.VData=1/3*h(1).^2;
        a3.UData=h(1);
        d.XData=[0,h(1),h(1)];
        d.YData=[1/3*h(1).^2,1/3*h(1).^2,0];
        set(slider, 'Value', h(1))
        drawnow
    end
因此,总代码:

function stackover()

clc,close all

fig=figure();

% initialize some parameters
xstart=4;
ystart=1/3*4^2;

ax=axes(fig,...
    'Units','Normalized',...
    'Position',[0.2,0.2,0.6,0.6],...
    'XGrid','on',...
    'YGrid','on');


slider=uicontrol(...
    'Parent',fig,...
    'Style','slider',...
    'Units','normalized',...
    'Position',[0.2,0.9,0.6,0.05],...
    'Tag','slider1',...
    'Min',0,...
    'Max',10,...
    'Value',xstart);

addlistener(slider,'Value',...
    'PostSet',@(hObject, event) slider_callback(slider, event));

h = impoint(gca,xstart,ystart);
setColor(h,'r')
point = h;
addNewPositionCallback(h,@(h) make_constraint(h));

x=linspace(0,10);
y=1/3*x.^2;
plot(x,y,'b-')
grid on
xlabel('x-axis')
ylabel('y-axis')
hold on
plot([-5,10],[0,0],'k-');
plot([0,0],[-5,35],'k-');

a1=quiver(0,0,xstart,ystart,0,...
    'LineWidth',1,...
    'Color','red');
a2=quiver(0,0,0,xstart,0,...
    'LineWidth',1,...
    'Color','red');
a3=quiver(0,0,xstart,0,0,...
    'LineWidth',1,...
    'Color','red');
d=plot([0,xstart,xstart],[ystart,ystart,0],'k--');
hold off

    function slider_callback(hObject,eventdata)
        x=hObject.Value;
        setPosition(point, [x 1/3*x^2])
        a1.UData=x;
        a1.VData=1/3*x.^2;
        a2.VData=1/3*x.^2;
        a3.UData=x;
        d.XData=[0,x,x];
        d.YData=[1/3*x.^2,1/3*x.^2,0];
        drawnow
    end

    function make_constraint(h)
        fcn = makeConstrainToRectFcn('impoint',[0 10],[1/3*h(1).^2 1/3*h(1).^2]);
        % Enforce boundary constraint function using setPositionConstraintFcn
        setPositionConstraintFcn(point,fcn);
        a1.UData=h(1);
        a1.VData=1/3*h(1).^2;
        a2.VData=1/3*h(1).^2;
        a3.UData=h(1);
        d.XData=[0,h(1),h(1)];
        d.YData=[1/3*h(1).^2,1/3*h(1).^2,0];
        set(slider, 'Value', h(1))
        drawnow
    end

end
ps
demo()
是一个现有的MATLAB函数,因此最好选择另一个名称


编辑2:

如果无法使用
impoint
,则必须添加3个侦听器:

  • WindowButtonUpFcn
    :检测鼠标何时释放
  • WindowButtonMotionFcn
    :检测鼠标何时移动
  • 按钮downfcn
    :在单击鼠标时检测
前2个需要附加到图中:

fig=figure('WindowButtonUpFcn',@drop,'WindowButtonMotionFcn',@move);
最后一个只能附加到绘图:

p=plot(xstart,ystart,'ro','ButtonDownFcn',@click);
由于
WindowButtonUpFcn
WindowButtonMotionFcn
用于整个图形,因此在移动或释放鼠标时始终会调用它们。但我们只希望在拖动点时执行函数。为此,需要一个变量(