当该点位于先前已“修补"的区域内时,如何获取图形的点(使用GUI中的回调)? [英] How to get point of a figure (using callbacks in GUI) when the point is inside a region that previously has been "patched"?
问题描述
我正在使用patch
以便将椭圆形内部绘制到在gui环境中创建的图形中.
I am using patch
in order to draw inside an ellipse into a figure I have created in gui environment.
通常,我通过单击(使用回调函数)来获得图形的点(坐标).当我要抓住的点不在先前绘制的椭圆内(应用patch
)时,它可以正常工作.
Normally, I get figures' points (coordinates) by clicking (using callback functions). It works properly when the point I want to grab is not inside an ellipse that I have previously plotted (applying patch
).
应用patch
后如何做才能在绘制椭圆后得到某个椭圆内的点?非常感谢!
What should I do after applying patch
in order to be able to get a point that is inside some ellipse after I have drawn it? Thanks a lot!
推荐答案
以下是解决问题的一种方法:
Here's a way to solve your problem:
首先,我们先画一个点,然后贴上一个覆盖"它的补丁.在此示例中,补丁是透明的,但仍无法选择其后面的点.
First we draw a point followed by a patch that "covers" it. In this example the patch is transparent, and still the point behind it cannot be selected.
(这部分代码取自MATLAB的 patch
)
(this part of the code is taken from MATLAB's example for patch
)
close all force; clear variables; clc;
h = plot(3,6,'o')
hold on;
xdata = [2 2 0 2 5;
2 8 2 4 5;
8 8 2 4 8];
ydata = [4 4 4 2 0;
8 4 6 2 2;
4 0 4 0 0];
cdata = [15 0 4 6 10;
1 2 5 7 9;
2 3 0 8 3];
p = patch(xdata,ydata,cdata,'Marker','o',...
'FaceColor','flat')
如果运行此代码,则应该得到如下输出:
If you run this code, you should get an output along the lines of:
h =
174.0110
p =
175.0105
其中显示了分配给轴的每个子轴的手柄.
Which shows the handles assigned to each child of the axes.
要获得更多见解,请添加以下附加代码:
To get some more insight, you add this additional code:
axes_children = get(gca,'Children')
disp(['Type of "point" plot: ' get(h,'type')]);
disp(['Type of "patch" plot: ' get(p,'type')]);
其输出是:
axes_children =
175.0105
174.0110
Type of "point" plot: line
Type of "patch" plot: patch
请注意元素的顺序: 175.0105 (即patch
)在列表中较高-这非常重要,因为您不能选择被另一个物体遮盖.
Notice the order of the elements: 175.0105 (i.e. the patch
) is higher in the list - this is very important, because you cannot select an object that is obscured by another object.
如果您有多个点\补丁,则可以使用以下类似方法将patch
es重新定位在point
下方:
In case you have multiple points\patches you can simply reposition the patch
es below the point
s using something like this:
for ind1=1:length(axes_children)
if strcmp(get(axes_children(ind1),'type'),'patch')
uistack(axes_children(ind1),'bottom');
end
end
这将使各点成为可选点,并在补丁彼此重叠的情况下保留补丁的顺序.
This will make the point(s) selectable and also preserve the order of the patches in case they overlap each other.
这是我使用为您的问题编译的一些鼠标跟踪代码的扩展示例.来自UndocumentedMatlab的想法.它可能会给您更多的想法...
Here's an extended example of the some mouse tracking code that I have compiled for your problem using idea from UndocumentedMatlab. It may give you some more ideas...
function init()
close all force; clear variables; clc;
%// Initialize the figure with a listener:
h = figure('WindowButtonMotionFcn',@windowMotion);
%// Add a "static" text label:
col = get(h,'color');
uicontrol('Style','text', 'Pos',[0,0,300,30],'Tag','lbl',...
'Background',col, 'HorizontalAlignment','left');
axes('units','pix'); hold all;
for i=1:3
X = 5*rand(100,1);
plot(X,rand*X + rand(100,1),'.');
end
xdata = [2 2 0 2 5;
2 8 2 4 5;
8 8 2 4 8]/2;
ydata = [4 4 4 2 0;
8 4 6 2 2;
4 0 4 0 0]/2;
cdata = [5 0 4 6 10;
1 2 5 7 9;
2 3 0 8 3];
patch(xdata,ydata,cdata,'Marker','o',...
'FaceColor','interp');
drawnow;
datacursormode on;
end
function windowMotion(hObject,eventData,varargin)
persistent inCallback;
%// If you want to do something complex inside the callback, the
%// inCallback lines makes sure that only 1 instance of the callback is
%// being executed at a time.
if ~isempty(inCallback), return; end
inCallback = true;
lbl = findobj('Tag','lbl');
try
currPos = get(gcf,'CurrentPoint');
ax_pos = get(gca,'Position');
%// Test if the mouse pointer is inside the axes:
if (currPos(1)>ax_pos(1) && currPos(1)<ax_pos(1)+ax_pos(3)) && ...
(currPos(2)>ax_pos(2) && currPos(2)<ax_pos(2)+ax_pos(4))
%// Find all possible
possible_points_obj = findobj(gca,'Type','line');
%// SOME LOGIC TO FIND THE CORRECT points_obj
%// In this example it will look only in the last-plotted group of
%// points - RED. This can be extended to loop over all "line"
%// objects and select the closest point of all.
correct_points_obj = possible_points_obj(1);
X=get(correct_points_obj,'XData')'; ...'
Y=get(correct_points_obj,'YData')'; ...'
XScale=diff(get(gca,'XLim'));
YScale=diff(get(gca,'YLim'));
currPosinAx = (currPos - ax_pos(1:2))./ax_pos(3:4).*[XScale YScale];
r=(((X-currPosinAx(1))./XScale).^2+((Y-currPosinAx(2))./YScale).^2);
[~,i]=min(r);
%// Here you put whatever you want to do with the point you found
set(lbl,'String',{['The closest point to the pointer is at: ('...
num2str(X(i)) ',' num2str(Y(i)) '),'];
['and belongs to handle: ' num2str(correct_points_obj)]});
else
set(lbl,'String','Mouse is outside axes');
end
catch
% error trapping here
end
drawnow;
inCallback = [];
end % myCallbackFcn1
这篇关于当该点位于先前已“修补"的区域内时,如何获取图形的点(使用GUI中的回调)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!