Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a MATLAB plot interactive?

Tags:

matlab

I'm trying to create a simple interface for plotting quadratic Lagrange polynomials. For this, you need just 3 points (with each their own x,y,z coordinates), which are then interpolated using the quadratic Lagrange polynomials.

It's easy to make a static version, or even one that lets the user input the 3 points before plotting the curve. But it should also be possible for the user to drag an existing point in the plot window to another position, and then re-plot the curve automatically using the new position of this point!

enter image description here

So in short, the user should be able to drag these black dots to another location. After that (or while dragging), the curve should be updated.

function Interact()

% Interactive stuff here

figure();
hold on;
axis([0 7 0 5])

DrawLagrange([1,1; 3,4; 6,2])

function DrawLagrange(P)

plot(P(:,1), P(:,2), 'ko--', 'MarkerSize', 10, 'MarkerFaceColor', 'k')

t = 0:.1:2;
Lagrange = [.5*t.^2 - 1.5*t + 1; -t.^2 + 2*t; .5*t.^2 - .5*t];

CurveX = P(1,1)*Lagrange(1,:) + P(2,1)*Lagrange(2,:) + P(3,1)*Lagrange(3,:);
CurveY = P(1,2)*Lagrange(1,:) + P(2,2)*Lagrange(2,:) + P(3,2)*Lagrange(3,:);

plot(CurveX, CurveY);

I think I either have to use functions like WindowButtonDownFcn, WindowButtonUpFcn and WindowButtonMotionFcn, or the ImPoint from the Image Processing Toolbox. But how?

[Edit] It should also work in 3D, since I'd like to generalize this concept to tensor product surfaces.

like image 779
Ailurus Avatar asked Mar 10 '12 11:03

Ailurus


2 Answers

A better solution (one that does not need any additional toolboxes) is to use events. First step:

H = figure('NumberTitle', 'off');
set(H, 'Renderer', 'OpenGL');

set(H, 'WindowButtonDownFcn', @MouseClick);
set(H, 'WindowButtonMotionFcn', @MouseMove);
set(H, 'WindowScrollWheelFcn', @MouseScroll);
set(H, 'KeyPressFcn', @KeyPress )

The next step is to define the functions like MouseClick, this is the place where you implement how to react to events (e.g. mouse buttons being clicked, keys being pressed).

In the meantime I implemented an interactive B-spline environment in MATLAB, the source code (along with a concise manual) can be downloaded from https://github.com/pjbarendrecht/BsplineLab.

like image 136
Ailurus Avatar answered Nov 14 '22 18:11

Ailurus


Great question! I've had this problem too and wondered how to solve it before, but never looked into it. My first thought was to use ginput and then minimize the distance to the line and find the closest point. I thought that was a bit of a hack so I looked around. Seems like that's the only reasonable answer out there and was confirmed here with this code as an example.

%minimum absolute differences kick in again
xx = 1:10; %xdata
yy = exp(xx);

plot(xx,yy);
[xm ym] = ginput(1); %xmouse, ymouse

%Engine
[~, xidx] = min(abs(xx-xm)); %closest index
[~, yidx] = min(abs(yy-ym));
x_closest = xx(xidx) %extract
y_closest = yy(yidx)

Not sure how it scales to 3D, but I thought this would be a good start.

like image 3
macduff Avatar answered Nov 14 '22 19:11

macduff