2015-12-07 2 views
0

Je suis plutôt nouveau à Matlab et peut-être que ce problème n'est pas difficile, mais j'ai des problèmes. Mon code ressemble à ceciRay et intersection de surface

x=-25:0.1:25; y=-25:0.1:25; [X,Y] = meshgrid(x,y); 
R=sqrt(X.^2+Y.^2); 
Z=sin(R); 

faces=delaunay(X,Y); 
alpha(0.3); 
trisurf(faces,X,Y,Z,'Edgecolor','none'); 
axis ([-20 20 -20 20 -1 51]); 
axis equal; 
xlabel('X'); 
ylabel('Y'); 
alpha(1); 
hold on 
syms t; 
x_source=20; 
x_dir=-2; 
y_source=0; 
y_dir=3; 
z_source=50; 
z_dir=-10; 

height_above_plane = @(t) z_source + t * z_dir - interp2(X, Y, Z, ... 
    x_source + t*x_dir, y_source + t*y_dir); 
t_intercept = fzero(height_above_plane, 0) 

x_ray = x_source + t_intercept * x_dir; 
y_ray = y_source + t_intercept * y_dir; 
z_ray = z_source + t_intercept * z_dir; 
plot(x_ray,y_ray,'r.','MarkerSize',10); 

Comme si le rayon commençait à une position 20; 0; 50. Ce que j'essaie de faire est une procédure de balayage laser virtuel. fzero me donne un NaN, quand x_dir dépasse un petit nombre et je n'arrive pas à comprendre pourquoi ... Toute aide serait grandement appréciée!

Le mauvais cycle après avoir résolu le problème:

t=0; 
x_source=20; 
y_source=0; 
z_source=50; 
z_dir=-10; 
for alfa=26:0.5:6 
x_dir=tand(alfa)*z_dir; 
    for beta=16:0.5:-16 
    y_dir=tand(beta)*z_dir;  
    y_dir=3; 
    height_above_plane = @(t) z_source + t * z_dir - interp2(X, Y, Z, ... 
    x_source + t*x_dir, y_source + t*y_dir,'linear',0); 
    t_intercept = fmincon(@(t) abs(height_above_plane(t)),0,[],[],[],[],4.5,6) 

    x_ray = x_source + t_intercept * x_dir; 
    y_ray = y_source + t_intercept * y_dir; 
    z_ray = z_source + t_intercept * z_dir; 
    plot(x_ray,y_ray,'k.','MarkerSize', 20); 
    end; 
end; 

Répondre

1

L'erreur complète est

Exiting fzero: aborting search for an interval containing a sign change 
    because NaN or Inf function value encountered during search. 
(Function value at -2.56 is NaN.) 
Check function or try again with a different starting value. 

et votre fonction évaluée à -2,56 ne revient en effet NaN. C'est parce que vous faites interp2(X,Y,Z,x_source + t*x_dir, y_source + t*y_dir) mais x_source-2.56*x_dir=25.12. Puisque vos données sont seulement pour x entre -25 et 25, vous devez extrapoler pour obtenir l'interpolant ici. Par défaut, Matlab renvoie NaN pour l'extrapolation, mais vous pouvez modifier la valeur en utilisant le cinquième argument facultatif à interp2, EXTRAPVAL (ajouter ,'linear',0 à l'appel interp2, vérifiez la documentation (0 peut-être pas un bon choix non plus)).

Étant donné que vous voulez contraint la résolution de racine, pensez à utiliser fmincon à la place, comme ceci:

t_intercept = fmincon(@(t) abs(height_above_plane(t)),0,[],[],[],[],-2.5,25/3) 

qui est plus lent, mais plus robuste, aussi longtemps que vous avez une façon de travailler ce que les limites t ont être.

+0

Merci beaucoup, ça a marché! Cependant, ma tentative de mettre ceci dans un cycle a échoué. Cela ne me donne aucune sorte d'erreur, donc encore une fois je ne sais pas quoi faire .. J'ai édité le message original pour montrer le cycle –

+0

Vous devrez changer 4.5 et 6 pour chaque itération que j'imagine. – David

+0

Oh, je pensais que c'était l'intervalle pour ma variable t. "solution est dans la plage de lb <= x <= ub" est ce que l'aide de Matlab dit –