在文本框中显示由imline创建的线的斜率

时间:2015-09-09 17:33:00

标签: matlab matlab-figure

此帖是该主题的延续:“Matlab imline snapping”已经解决。以下是将imline对象捕捉到曲线的工作代码。

function calc_slope(handle,event)

axis_h   = findobj(gcf,'Type','axes');
obj_h    = get(axis_h,'Children');
obj_type = get(obj_h,'Type');
if ~iscell(obj_type),obj_type = cellstr(obj_type);end

for i=1:length(obj_type)
    if strcmpi(obj_type{i},'line'),data = obj_h(i);end
end
xdata  = get(data,'XData');
ydata  = get(data,'YData');

on = get(handle,'State');
if strcmpi(on,'on') || strcmpi(on,'off'),

    fcn_constr = @(pos) imline_snap(pos, [xdata(:) ydata(:)]); 

    xy = imline(axis_h, 'PositionConstraintFcn', fcn_constr);

    addNewPositionCallback(xy,@(pos) disp_slope(pos));     
end


function constr_pos = imline_snap(new_pos, positions)

[~, ind1] = min(sum(bsxfun(@minus, new_pos(1,:), positions).^2, 2));
[~, ind2] = min(sum(bsxfun(@minus, new_pos(2,:), positions).^2, 2));

constr_pos = [positions(ind1,:); positions(ind2,:)];


function disp_slope(pos)

delete(findobj(gca,'Type','text'));

text((pos(1)+pos(2))/2,(pos(3)+pos(4))/2,['\DeltaY/\DeltaX = ',num2str((pos(4)-pos(3))/(pos(2)-pos(1))),...
                '    [\DeltaX = ',num2str(pos(2)-pos(1)),', \DeltaY = ',num2str((pos(4)-pos(3))),']']);

每次图形工具栏上的切换按钮切换(打开和关闭)时,都会抛出一个新的imline对象。有许多图形具有不同的参数,因此必须从图中提取数据。在给定的图中,可以有多个对象:imline对象,文本和/或行;因此,calc_slope函数中的前七行。

imline对象捕捉到曲线的最近数据点,它由imline_snap函数完美地完成,这是“Luis Mendo”的答案。非常感谢。这是一个最头痛的问题。

现在最后一个问题是在文本框中显示imline对象的斜率(而不是标题或浮动框)。它是在disp_slope函数中尝试的(而且很悲惨)。

我正在做“删除(findobj(gca,'Type','text'));”只是因为没有这样的东西,当imline对象被移动时,它将留下数百万个文本框。我只想显示一个最新的斜率计算。

“删除(findobj(gca,'Type','text'));”有多个问题。“如果我停止移动线,它将很好地显示最后的斜率计算。但是,只要我抛出另一个imline对象并移动新的imline对象,第一个imline对象中的文本框就会被删除,当然。

另一个问题是,即使我删除了imline对象,相关的文本框也会保留。

总之,

  1. 我想在文本框中显示当前计算的斜率
  2. 即使有多个imline对象,我希望每个imline对象的文本框都保留。
  3. 最后,我希望删除特定的imline对象时相应的文本框也会消失。
  4. 可以这样做吗?请帮助。

    谢谢,

    埃里克

1 个答案:

答案 0 :(得分:2)

每次都不要创建新的文本对象。最初创建一个

ht = text(.45, .85, ''); %// modify coordinates to place it where you want

然后'String'更改时更新其内容(imline属性)。要进行更新,请修改imline_snap函数以接受ht作为第三个输入,并在结尾处添加以下行:

set(ht, 'String', ...
    num2str((constr_pos(2,2)-constr_pos(1,2))/(constr_pos(2,1)-constr_pos(1,1))));

因此功能变为

function constr_pos = imline_snap(new_pos, positions, ht)
[~, ind1] = min(sum(bsxfun(@minus, new_pos(1,:), positions).^2, 2));
[~, ind2] = min(sum(bsxfun(@minus, new_pos(2,:), positions).^2, 2));
constr_pos = [positions(ind1,:); positions(ind2,:)];
set(ht, 'String', ...
        num2str((constr_pos(2,2)-constr_pos(1,2))/(constr_pos(2,1)-constr_pos(1,1))));

然后,在定义fcn_contr时,将引用ht传递给文本对象:

fcn_constr = @(pos) imline_snap(pos, [xdata(:) ydata(:)], ht); 

这是一个例子,借用my previous answer的曲线:

h = plot(0:.01:1, (0:.01:1).^2); %// example curve. Get a handle to it
a = gca; %// handle to current axes
ht = text(.45, .85, ''); %// create text
xdata = get(h,'XData'); %// x values of points from the curve
ydata = get(h,'YData'); %// y values of points from the curve
fcn_constr = @(pos) imline_snap(pos, [xdata(:) ydata(:)], ht); %// particularize function
imline(a, 'PositionConstraintFcn', fcn_constr); %// create imline

enter image description here

您还可以更新文字位置('Position'属性)。只需更改imline_snap的最后一个语句即可包含该语句。例如:

set(ht, 'String', ...
        num2str((constr_pos(2,2)-constr_pos(1,2))/(constr_pos(2,1)-constr_pos(1,1))), ...
        'Position', ...
        mean(constr_pos) + [.03 -.03]); %// manually adjust offset if needed

偏移量[.03 -.03]旨在避免文本与行重叠。您可能需要更改它。此外,使用粗体创建文本对象可能会有所帮助。该行成为

ht = text(.45, .85, '', 'Fontweight', 'bold'); %// create text, in boldface

以下是更新文字位置的示例:

enter image description here

在您删除所需的imline对象和event listener删除关联的文本对象。这是一个具有三个主要属性的对象:源对象的单元数组,事件和回调函数。当指定的事件发生在其中一个源对象上时,执行事件监听器的回调函数。

要为imline对象的删除创建事件侦听器,请使用该对象的addEventListener方法并指定事件名称和回调函数。回调函数是通过function handle指定的,它应该有两个输入,它们对应于源对象和事件(这就是回调函数将如何知道"为什么"它&# 39;被称为)。即使这些输入实际上没有被使用,也需要以这种方式定义函数。

在这种情况下,我们要监听的事件是ObjectBeingDestroyed,源对象是imline对象,回调函数是delete(ht)(删除文本对象) 。因此,上例中的代码变为

h = plot(0:.01:1, (0:.01:1).^2); %// example curve. Get a handle to it
a = gca; %// handle to current axes
ht = text(.45, .85, '', 'Fontweight', 'bold'); %// create text, in boldface
xdata = get(h,'XData'); %// x values of points from the curve
ydata = get(h,'YData'); %// y values of points from the curve
fcn_constr = @(pos) imline_snap(pos, [xdata(:) ydata(:)], ht); %// particularize function
hi = imline(a, 'PositionConstraintFcn', fcn_constr); %// create imline and get a handle
addlistener(hi, 'ObjectBeingDestroyed', @(obj,event) delete(ht))

其中只有最后两行是新的。

现在每当删除imline对象时,都会执行操作delete(ht),从而删除文本对象。