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!
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With