提问人:Andrew 提问时间:11/7/2023 最后编辑:Cris LuengoAndrew 更新时间:11/7/2023 访问量:21
使用回调来识别 3D 图上的鼠标选定点,有时只能在另一个 m 文件中作为函数工作,为什么?
Using a Callback to identify a mouse selected point on a 3-D plot, sometimes only works inside another m-file as a function, why?
问:
在解决“识别 3D 图上的鼠标选定点”问题时,建议使用回调函数来保持对图的交互式关注并选择/识别任意数量的点,我遇到了以下奇怪的行为。
唯一错误地使用欧几里得计算的 Matlab“答案”,所以我将其改编为 Octave,并在此处提供了更好的 3D 最小面积解决方案作为完整代码。
我无法弄清楚的是,当我尝试将代码复制到模糊逻辑文件(非功能)中时,它无法正常工作,在==>“句柄无法识别......”处抛出错误。我把声明放在哪里并不重要。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
如果删除文件顶部的行,则 M 文件是脚本,函数是本地函数。作为局部函数,它无权访问自身外部定义的变量。在函数之前或之后在脚本中定义的任何变量在函数中都不可见。function
click
但请注意,Octave 不允许在脚本 M 文件的末尾使用本地函数,因此在使用时不会定义。在MATLAB中,它可以工作,但在Octave中则不行。在 Octave 中,您必须先将函数声明移动到脚本中的某个点,然后才能使用它。click
在这种形式中,您必须将句柄作为参数传递到函数中。例如,您可以定义
function click(handle,src)
然后,作为回调传递的句柄将是 。@click
@(src,~)click(handle,src)
评论