Paulius Razma
Paulius Razma

Reputation: 3

Ray and surface intersection

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

Answers (1)

David
David

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

Related Questions