2012-03-10 39 views
15

İkinci dereceden Lagrange polinomlarını çizmek için basit bir arayüz oluşturmaya çalışıyorum. Bunun için, sadece 3 puan (her biri kendi x, y, z koordinatları ile) gerekir, bunlar daha sonra ikinci dereceden Lagrange polinomları kullanılarak enterpolasyona tabi tutulur.MATLAB arsa nasıl interaktif hale getirilir?

Bu statik bir sürümünü yapmak kolaydır, ya eğrisinin çizilmesi önce kullanıcı girişi 3 puan sağlar hatta bir. Ancak, kullanıcının mevcut bir noktayı çizim penceresinde başka bir konuma sürüklemesi ve bu noktanın yeni konumunu kullanarak eğriyi otomatik olarak yeniden oluşturması da mümkün olmalıdır!

enter image description here

Yani kısacası, kullanıcı başka bir konuma bu siyah noktalar sürüklemek mümkün olmalıdır. Bundan sonra (veya sürüklerken), eğri güncellenmelidir.

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); 

Ben de ve WindowButtonMotionFcn, WindowButtonDownFcn, WindowButtonUpFcn veya Görüntü İşleme Toolbox dan ImPoint gibi işlevleri kullanmak zorunda düşünüyorum. Ama nasıl?

[Düzenle] Ben ürün yüzeyleri tensör bu kavramı genelleme istiyorum çünkü Ayrıca, 3D çalışmalıdır.

+0

Hiç bunu linkdata ile çözmeyi denediniz mi? –

cevap

3

Harika soru! Bu problemi de yaşadım ve daha önce nasıl çözeceğimi merak ettim, ama asla ona bakmadım. İlk düşüncem ginput'u kullanmak ve sonra çizgiye olan mesafeyi en aza indirmek ve en yakın noktayı bulmaktı. Bunun bir kesmek olduğunu düşündüm, bu yüzden etrafa baktım. o orada sadece makul bir cevap ve

%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) 

o 3D'ye ölçekler nasıl emin değil here with this code as an example. doğrulandı ama bu iyi bir başlangıç ​​olacağını düşündüm gibi görünüyor.

+0

Teşekkürler, _ginput_ seçeneğini bilmiyordum! Ancak, bir noktayı sürüklemek mümkün değil, ya da değil mi? Sadece ** ImPoint ** hakkında daha fazla bilgi/örnek aradı ve basit bir senaryo yazdı. Bunu bir cevap olarak göndereceğim, ancak 3D için çalışmadığı için kendi yanıtımı kabul etmeyeceğim. Ama belki de bazı insanlar yararlı bulacaktır. – Ailurus

12

Tamam, Görüntü İşleme Araç Kutusu'ndan ImPoint seçeneğiyle ilgili daha fazla bilgi aradım ve bu komut dosyasını yazdım.

PostScript'dan beri yalnızca bir 2D ayarı için çalışır (ve eğriler yerine yüzeylerle çalışabilmek için bunu 3B'ye genelleştirmek istiyorum), bu gerçekten kabul edilebilir bir yanıt değildir! Ama birileri bundan fayda sağlayabilir veya 3D olarak nasıl yapılacağını öğrenebilir.

% ------------------------------------------------- 
% This file needs the Image Processing Toolbox! 
% ------------------------------------------------- 

function Interact(Pos) 

% This part is executed when you run it for the first time. 
% In that case, the number of input arguments (nargin) == 0. 
if nargin == 0 

    close all; 
    clear all; 
    clc; 

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

    % I do not know how to do this without global variables? 
    global P0 P1 P2 

    % GCA = Get handle for Current Axis 
    P0 = ImPoint(gca,1,1); 
    setString(P0,'P0'); 
    P1 = ImPoint(gca,2,4); 
    setString(P1,'P1'); 
    P2 = ImPoint(gca,6,2); 
    setString(P2,'P2'); 

    % Call subfunction 
    DrawLagrange(P0,P1,P2) 

    % Add callback to each point 
    addNewPositionCallback(P0,@Interact); 
    addNewPositionCallback(P1,@Interact); 
    addNewPositionCallback(P2,@Interact); 

else 

    % If there _is_ some input argument, it has to be the updated 
    % position of a moved point. 
    global H1 H2 P0 P1 P2 

    % Display X and Y coordinates of moved point 
    Pos 

    % Important: remove old plots! Otherwise the graph will get messy. 
    delete(H1) 
    delete(H2) 
    DrawLagrange(P0,P1,P2) 

end 

function DrawLagrange(P0,P1,P2) 

P = zeros(3,2); 
% Get X and Y coordinates for the 3 points. 
P(1,:) = getPosition(P0); 
P(2,:) = getPosition(P1); 
P(3,:) = getPosition(P2); 

global H1 H2 
H1 = plot(P(:,1), P(:,2), 'ko--', 'MarkerSize', 12); 

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,:); 

H2 = plot(CurveX, CurveY); 

Açıklık için bazı yorumlar ekledim.

[Düzenle] Önizleme sözdizimi vurgulaması çok iyi görünmüyor! Bir yerde vurgulanacak dili tanımlamalı mıyım?

+0

Bu komut dosyasını test etmek için, bunu ** Interact.m ** olarak kaydedin ve _without_ giriş argümanlarını çağırın. – Ailurus

6

Daha iyi bir çözüm (herhangi bir ek araç kutularınızı gerekmez bir) olayları kullanmaktır. Birinci adım:

sonraki adım MouseClick gibi işlevleri tanımlamaktır
H = figure('NumberTitle', 'off'); 
set(H, 'Renderer', 'OpenGL'); 

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

, bu olaylara nasıl tepki verileceğini uygulamak yerdir (örneğin fare butonları tuşları basılmasını, tıklandığını).Ben MATLAB'te interaktif B-parça ortamı uygulanan arada

, (özlü kılavuzu ile birlikte) kaynak kodu https://github.com/pjbarendrecht/BsplineLab indirilebilir.

+0

Link artık mevcut değildir! – Arash

+0

@Arash Haklısınız, eski üniversitem sayfayı birkaç hafta önce çıkardı. Gelişmiş bir sürüm için bir GitHub sayfası oluşturabilir veya Geogebra için benzer bir şey yazabilirim :) – Ailurus

+0

teşekkürler, bekliyoruz :) – Arash

İlgili konular