Reputation: 3
I'm rather new to Matlab and perhaps this problem isn't difficult, yet I'm having problems. My code looks like this
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);
As if the ray starts at a position 20;0;50. What I'm trying to make is a virtual laser scan procedure. fzero gives me a NaN, when x_dir exceeds a small number and I can't figure out why... Any help would be greatly appreciated!
The bad cycle after solving the problem:
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;
Upvotes: 0
Views: 215
Reputation: 8459
The full error is
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.
and your function evaluated at -2.56 does indeed return NaN
. This is because your are doing interp2(X,Y,Z,x_source + t*x_dir, y_source + t*y_dir)
but x_source-2.56*x_dir=25.12
. Since your data is only for x
between -25 and 25, you have to extrapolate to get the interpolant here. By default, Matlab returns NaN
for extrapolation, but you can change the value using the optional fifth argument to interp2
, EXTRAPVAL
(add ,'linear',0
to the interp2
call, check the documentation (0 might not be a good choice either)).
Given you want constrained root solving, consider using fmincon
instead, like this:
t_intercept = fmincon(@(t) abs(height_above_plane(t)),0,[],[],[],[],-2.5,25/3)
which is slower, but more robust, as long as you have a way of working out what the limits on t
have to be.
Upvotes: 1