Matlab imline捕捉 [英] Matlab imline snapping
问题描述
有没有办法让由 imline
创建的一条线的末端对齐曲线上最近的数据点?
我试图测量曲线上两点之间的斜率。 imline
很好,但它创建的线的末端不会捕捉到曲线上的数据点。
我想知道是否可以在线的两端保持曲线时拖动线。
可以使用Is there a way to make the ends of a line created by imline
snap to the nearest data point on a curve?
I'm trying to measure the slope between two points on a curve. The imline
is great, but the ends of the line created by it do not snap to data points on a curve.
I'm wondering if I can drag the line around while both ends of the line remained on the curve.
It can be done using the 'PositionConstraintFcn'
property of imline
. Its value specifies a function handle that is called whenever the line is dragged using the mouse:
'PositionConstraintFcn'
: Function handle fcn that is called whenever the line is dragged using the mouse.Whenever the object is moved because of a mouse drag, the constraint function is called using the syntax:
constrained_position = fcn(new_position)
wherenew_position
is of the form [...]
The form of new_position
is a 2x2 matrix, where each row is an endpoint of the line; and columns represent x and y respectively.
So all you have to do is specify a function that finds the closest point for each end and returns that constrained position. This can be done in two steps:
Create a function to do the actual job, using as inputs the new position (
2
x2
matrix) and the set of allowed positions (N
x2
, whereN
represents the number of points of the curve). The output is a2
x2
matrix with the constrained position.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,:)];
Define this function in its own m-file (
imline_snap.m
) and place it where Matlab can find it, for example in the current folder.Here's how it works. The function receives the two points selected by the mouse (
new_pos
) and the set of points defining the curve (positions
). It computes the distance from the first mouse point to each point in the curve (sum(bsxfun(@minus, new_pos(1,:), positions).^2, 2)
), and gets the index of the point in the curve with minimum distance (ind1
). The same is done for the second point (giving the indexind2
). Finally, those indices are used for selecting the appropriate curve points and building the ouput (constr_pos
).The above
imline_snap
function needs to be particularized with the allowed positions corresponding to the points of the curve. This is necessary because thePositionConstraintFcn
must accept only one input, namely the first input ofimline_snap
. This can be done via an anonymous function (see the example below, linefcn = ...
); whose handle is then passed toimline
.
Example code:
h = plot(0:.01:1, (0:.01:1).^2); %// example curve. Get a handle to it
a = gca; %// handle to current axes
X = get(h,'XData'); %// x values of points from the curve
Y = get(h,'YData'); %// y values of points from the curve
fcn = @(pos) imline_snap(pos, [X(:) Y(:)]); %// particularize function using curve points
imline(a, 'PositionConstraintFcn', fcn) %// create imline with that PositionConstraintFcn
It should be noted that the code snaps to actual curve points. It doesn't for example interpolate between curve points. That could be done modifying the imline_snap
function accordingly (but could result in sluggish movement if the number of operations is large).
Here's the above example at work (in Matlab R2010b). The righmost endpoint of the curve was dragged arbitrarily with the mouse, but it is seen to be snapped to the curve.
As a bonus, it would be easy to modify the function to display the slope in the figure title. Just add the following line at the end of the imline_snap
function:
title(['Slope: ' num2str((constr_pos(2,2)-constr_pos(1,2))/(constr_pos(2,1)-constr_pos(1,1)))])
Example showing slope:
这篇关于Matlab imline捕捉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!