在处理“识别 3D 绘图上的鼠标选定点”问题时,建议使用回调函数来保留绘图上的交互焦点并选择/识别任意数量的点,我遇到了以下奇怪的行为.
唯一错误地使用欧几里德计算的 Matlab“答案”,因此我将其改编为 for Octave 并且我在这里提供了一个更好的 3-D 最小面积解决方案作为完整代码。
我无法弄清楚的是,当我尝试将代码复制到模糊逻辑文件(非功能性的 m 文件)时,它无法工作,并在
Pt = get(handle.a, "CurrentPoint")
==>“句柄无法识别..”处抛出错误。 。” 我将 handle.a=axes
声明放在哪里并不重要。
这里提供的版本与 M 文件作为函数或不一样工作,但是一旦我将它放入包含其他代码的文件中,而不仅仅是简单的向量语句,如果主文件不是“函数”,它就会失败-m-文件”
我纯粹是猜测工作,并将“函数”添加到文件顶部并保存它,有人可以解释为什么吗?
function Interactive_surf
format short;
handle.a = axes;
Xt = [0 0.71429 1.4286 2.1429 2.8571 3.5714 4.2857 5 5.7143 6.4286 7.1429 7.8571 8.5714 9.2857 10];
Yt = [0 0.71429 1.4286 2.1429 2.8571 3.5714 4.2857 5 5.7143 6.4286 7.1429 7.8571 8.5714 9.2857 10];
Z = [ 6.2518 6.4574 7.0428 8.1286 9.3374 10.149 10.435 10.462 10.435 10.531 11.293 12.839 14.343 14.955 15;
7.0713 7.2578 7.7689 8.7243 9.7992 10.528 10.786 10.81 10.786 10.542 11.306 12.856 14.362 14.971 15.015;
8.2585 8.432 9.0076 9.789 10.672 11.272 11.486 11.506 11.486 11.272 11.516 13.118 14.652 15.218 15.247;
9.7942 9.9353 10.715 12.178 12.698 13.041 13.161 13.172 13.161 13.041 12.698 14.456 16.12 16.419 16.386;
11.446 11.556 12.295 14.137 16.275 16.06 15.987 15.98 15.987 16.06 16.275 17.449 19.288 18.78 18.699;
12.902 12.988 13.682 15.392 17.287 18.291 18.598 18.572 18.598 18.877 19.709 21.084 22.69 21.138 21.166;
13.936 14.007 14.664 16.27 17.992 18.872 19.229 19.401 19.481 19.815 20.77 22.286 23.469 22.158 22.181;
14.532 14.594 15.229 16.77 18.394 19.207 19.537 19.703 19.781 20.116 21.061 22.519 23.532 22.807 22.827;
14.819 14.878 15.5 17.01 18.586 19.368 19.686 19.848 19.925 20.26 21.198 22.625 23.602 23.454 23.469;
14.937 14.993 15.611 17.108 18.665 19.434 19.747 19.907 19.984 20.319 21.253 22.667 23.962 24.001 24.011;
14.979 15.035 15.652 17.143 18.694 19.457 19.769 19.929 20.005 20.34 21.273 22.682 23.97 24.394 24.396;
14.995 15.051 15.667 17.157 18.704 19.466 19.777 19.937 20.013 20.348 21.281 22.688 23.973 24.651 24.651;
15 15.056 15.671 17.161 18.707 19.469 19.78 19.939 20.016 20.351 21.283 22.69 23.974 24.674 24.803;
15 15.056 15.671 17.161 18.707 19.469 19.78 19.939 20.016 20.351 21.283 22.69 23.974 24.674 24.89;
15 15.056 15.671 17.161 18.707 19.469 19.78 19.939 20.016 20.351 21.283 22.69 23.974 24.674 24.922];
## Assign raw data to the handle structure
handle.x = Xt;
handle.y = Yt;
handle.z = Z; ## NOTE the Z-matrix has columns as X-axisvalues and
### Plot in 3D with CallBack function called
handle.p = surf(handle.x,handle.y,handle.z, 'ButtonDownFcn', {@click});
xlabel('x-axis');
ylabel('y-axis');
zlabel('z-axis');
grid on
function click(src,~)
## Get current perpendicular screen vector
Pt = get(handle.a, "CurrentPoint")
### Sort through every point in the surface to find the smallest Area to the point
for dy= 1:15
for dx = 1:15
surf_Pt(dx, :) = [handle.x(dx) handle.y(dy) handle.z(dy, dx)];
v1 = surf_Pt(dx, :) - Pt(1,:); ## Position vectors: line vector end point to
v2 = surf_Pt(dx, :) - Pt(2,:); ## existing surface grid points
X_Prod = cross(v1, v2); ## Vector Cross product gives normal vector
Mag_X_Prod = norm(X_Prod); ## |normal vector|==> Area of //pipehead
Area(dx, dy) = 0.5*Mag_X_Prod; ## Store each area of triangle
endfor
endfor
[row, col] = find(Area == min(Area(:)))
str = 'min_Area = %d';
str1 = sprintf(str, Area(row, col));
disp(str1)
# Display the selected point on 3D plot.
# Points on the fence may not generate a label,
# so rotate the image so as it shows inside the grid, then click.
formatSpec = "Pt clicked = [%d %d %d]";
point_text_val = [handle.x(row) handle.y(col) handle.z(col, row)];
pos_text_z = (handle.z(col, row))+0.2;
str = sprintf(formatSpec, point_text_val)
text(handle.x(row), handle.y(col), pos_text_z, str,'FontSize',18)
## NOTES
## The figure properties "alphamap" would be used to modify the transparency
## of the axes frame and allow visiblity of the labels added above that
## run off behind the 100%-white fence SADLY
## "Transparency is not yet implemented for figure objects. alphamap is unused"
endfunction
end
在发布的代码中,
click
是一个嵌套函数。作为嵌套函数,它可以访问父函数中定义的变量。
如果删除文件顶部的
function
行,则M文件是一个脚本,并且函数click
是一个本地函数。作为局部函数,它无权访问在其外部定义的变量。在函数之前或之后的脚本中定义的任何变量在函数内部都是不可见的。
但请注意,Octave 不允许在脚本 M 文件末尾添加本地函数,因此使用时不会定义
click
。在 MATLAB 中它可以工作,但在 Octave 中不行。在 Octave 中,您必须在使用函数声明之前将其移动到脚本中的某个位置。
在这种形式中,您必须将句柄作为参数传递给函数。例如,您可以定义
function click(handle,src)
然后,您作为回调传递的句柄将是
@click
,而不是 @(src,~)click(handle,src)
。