射线与曲面相交
Ray and surface intersection
我是 Matlab 的新手,也许这个问题并不难,但我遇到了问题。我的代码看起来像这样
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);
好像光线从位置 20;0;50 开始。我想做的是一个虚拟激光扫描程序。 fzero 给了我一个 NaN,当 x_dir 超过了一个小数字,我不知道为什么...任何帮助将不胜感激!
解决问题后的坏循环:
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;
完整的错误是
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.
并且您的函数在 -2.56 处评估确实 return NaN
。这是因为您正在做 interp2(X,Y,Z,x_source + t*x_dir, y_source + t*y_dir)
但 x_source-2.56*x_dir=25.12
。由于您的数据仅适用于 -25 到 25 之间的 x
,因此您必须在此处进行推断以获取插值。默认情况下,Matlab returns NaN
用于外推,但您可以使用可选的第五个参数将值更改为 interp2
、EXTRAPVAL
(将 ,'linear',0
添加到interp2
打电话,查看文档(0 也可能不是一个好的选择)。
鉴于您想要约束根求解,请考虑改用 fmincon
,如下所示:
t_intercept = fmincon(@(t) abs(height_above_plane(t)),0,[],[],[],[],-2.5,25/3)
速度较慢,但更稳健,只要您有办法计算出 t
的限制。
我是 Matlab 的新手,也许这个问题并不难,但我遇到了问题。我的代码看起来像这样
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);
好像光线从位置 20;0;50 开始。我想做的是一个虚拟激光扫描程序。 fzero 给了我一个 NaN,当 x_dir 超过了一个小数字,我不知道为什么...任何帮助将不胜感激!
解决问题后的坏循环:
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;
完整的错误是
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.
并且您的函数在 -2.56 处评估确实 return NaN
。这是因为您正在做 interp2(X,Y,Z,x_source + t*x_dir, y_source + t*y_dir)
但 x_source-2.56*x_dir=25.12
。由于您的数据仅适用于 -25 到 25 之间的 x
,因此您必须在此处进行推断以获取插值。默认情况下,Matlab returns NaN
用于外推,但您可以使用可选的第五个参数将值更改为 interp2
、EXTRAPVAL
(将 ,'linear',0
添加到interp2
打电话,查看文档(0 也可能不是一个好的选择)。
鉴于您想要约束根求解,请考虑改用 fmincon
,如下所示:
t_intercept = fmincon(@(t) abs(height_above_plane(t)),0,[],[],[],[],-2.5,25/3)
速度较慢,但更稳健,只要您有办法计算出 t
的限制。