how to allow user to get an arbitrary line profile from a contourplot

lets say we have a slice figure:
[X Y Z]=meshgrid([-2:.1:2],[-2:.1:2],[-2:.1:2]);
f=rand(41,41,41);
slice(X,Y,Z,f,0,[],[])
I want the user to be able to use the cursor to draw a line across the slice profile and have matlab open a second figure and plot values of f along that line.

댓글 수: 1

You might want to make your question more specific. Is the question about how to draw the line? How to define the line with the cursor (and what does that mean? Are you selecting one, two, 600 points to define the line?) How to interpolate f long the line?

댓글을 달려면 로그인하십시오.

답변 (3개)

A
A 2012년 5월 3일

0 개 추천

I need the code to allow user to be able to click on one corner of the slice, hold the left mouse button, and drag cursor to some other corner of the slice, and then let go of the left mouse button, to define a straight line (or alternatively, click on two points to define a line).
here is a demonstration: (done in another program)
f has values defined at all points within that slice. Therefore no interpolation should be required.

댓글 수: 5

Would a slider perhaps make more sense as a user interface?
what do you mean?
Instead of having the user click to position the line, there would be a line always shown and the corresponding profile, and there would be a slider that the user could reposition to move the line up or down.
I have not been entirely clear whether the profile lines to be draw are always horizontal, or always vertical, or either horizontal or vertical but not angled, or angle allowed ?
I would accept a slider implementation.
There are no constraints on orientation of the line specifid by user (see video link above)
The video is rendered by flash on that site. Flash is often considered a security risk, and there are now a number of browsers which do not support flash at all.

댓글을 달려면 로그인하십시오.

Sean de Wolski
Sean de Wolski 2012년 5월 4일

0 개 추천

I already gave you code that with a little bit of modification could easily do this. Alternatively, you could take another approach:
Have the axes buttondownfcn make note of the current point and set the windowbuttondownfcn to draw a line from the mouse position to that point, as well as set the buttonupfcn to make a note of the new current point and turn off the windowbuttonmotion function. At this point you now know the two endpoints, you can draw line between them and interpolate to this line as necessary.

댓글 수: 4

"Therefore no interpolation should be required" was written above, which implies that the lines are restricted to horizontal or vertical or a 45 degree diagonal.
So then as the user moves the mouse pointer, the line could be drawn to the nearest point that makes a line matching these constraints.
What I meant by no interpolation required is that function f has values defined at every point in XY plane. All I need is plot values of f falling under user-defined line. The line can be defined by ANY two points in XY plane within the slice. It is not constrained to horizontal or vertical or a 45 degree diagonal.
In such a case, the number of points on the line would be variable, and a grid point that was just barely touched would be given as much output weight as a grid point that was fully traversed. The common method to deal with these difficulties is to choose a constant number of points for the profile, divide the distance up in to equal segments, and then to interp the locations so deduced.

댓글을 달려면 로그인하십시오.

What you're asking to do isn't something that's going to have an off-the-shelf solution. You need to build it yourself.
To do it you'll need to learn about things like the Figure window event callbacks, passing data between callbacks, etc. For this specific application, understanding the axes CurrentPoint and data interpolation is also needed.
Here's a toy example that could be a good starting point. I'm sure it doesn't do everything and exactly what you want. But if you can understand what it's doing you should be able to extend it to your application:
function sample
[x,y,z] = peaks;
f = figure( ...
'WindowButtonDownFcn', @onMouseDown, ...
'WindowButtonUpFcn', @onMouseUp, ...
'WindowButtonMotionFcn', @onMouseMove );
a = axes('Parent', f);
pcolor(a,x,y,z);
L = line('XData', [], 'YData', [], 'Parent', a);
setappdata(f, 'MouseIsPressed', false);
setappdata(f, 'LineHandle', L);
setappdata(f, 'AxesHandle', a);
setappdata(f, 'FirstLinePoint', [0 0]);
setappdata(f, 'SurfaceData', {x; y; z});
function onMouseDown(src, evt)
setappdata(src, 'MouseIsPressed', true);
setappdata(src, 'FirstLinePoint', ...
get( getappdata( src, 'AxesHandle' ), 'CurrentPoint' ) );
function onMouseUp(src, evt)
setappdata(src, 'MouseIsPressed', false);
L = getappdata(src, 'LineHandle');
x = get( L, 'XData' );
y = get( L, 'YData' );
set( L, 'XData', [], 'YData', [] );
x_interp_pts = linspace(x(1), x(2), 30);
y_interp_pts = linspace(y(1), y(2), 30);
origdata = getappdata(src, 'SurfaceData');
z_interp = interp2( origdata{1}, origdata{2}, origdata{3}, x_interp_pts, y_interp_pts );
figure;
plot(z_interp, '.-');
function onMouseMove(src, evt)
if getappdata(src, 'MouseIsPressed')
firstPoint = getappdata(src, 'FirstLinePoint');
secondPoint = get( getappdata(src, 'AxesHandle'), 'CurrentPoint' );
set( getappdata(src, 'LineHandle'), ...
'XData', [firstPoint(1) secondPoint(1)], ...
'YData', [firstPoint(3) secondPoint(3)] );
end

카테고리

도움말 센터File Exchange에서 2-D and 3-D Plots에 대해 자세히 알아보기

태그

질문:

A
A
2012년 4월 30일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by