如何通过鼠标点击获取Mayavi 3D绘图中任意点的数据及坐标
Mayavi 3D地形模型点击取坐标实现方案
核心原理
Mayavi的事件绑定逻辑和Matplotlib类似,通过给场景绑定鼠标拾取回调,即可在点击3D模型时获取对应位置的世界坐标,你只需要在回调中追加自己的坐标转图像坐标逻辑即可。
可直接运行的示例代码
import numpy as np from mayavi import mlab # -------------------------- 替换为你自己的DEM数据 -------------------------- # 这里用模拟地形做演示,你可以直接替换为自己的x/y/z高程数据 x_grid, y_grid = np.mgrid[-100:100:200j, -100:100:200j] dem_z = np.sin(np.hypot(x_grid, y_grid)/10) * 15 + np.random.normal(0, 0.5, x_grid.shape) # 构建3D地形模型 surface = mlab.surf(x_grid, y_grid, dem_z, warp_scale=1, colormap='terrain') mlab.axes(xlabel='东向坐标', ylabel='北向坐标', zlabel='高程') mlab.colorbar(title='高程值') # -------------------------- 点击事件回调函数 -------------------------- def on_click_pick(picker): # 过滤点击空白区域的无效触发 if picker.actor is None: return # 获取点击位置的3D世界坐标,和你输入DEM的坐标空间完全一致 click_x, click_y, click_z = picker.pick_position print(f"拾取坐标:X={click_x:.2f}, Y={click_y:.2f}, Z={click_z:.2f}") # ------------ 在此处追加你自己的坐标映射逻辑 ------------ # 示例:获取点击位置对应DEM数组的索引 # x_idx = np.argmin(np.abs(x_grid[:,0] - click_x)) # y_idx = np.argmin(np.abs(y_grid[0,:] - click_y)) # print(f"对应DEM数组索引:行={x_idx}, 列={y_idx}, 高程值={dem_z[x_idx, y_idx]:.2f}") # -------------------------- 绑定鼠标左键点击事件 -------------------------- # button参数可改为'Middle'/'Right'绑定中键/右键事件 mlab.gcf().on_mouse_pick(on_click_pick, button='Left') mlab.show()
关键说明
- 无效点击过滤:回调中对
picker.actor做非空判断,是为了避免用户点击场景空白区域时返回无意义的坐标 - 坐标兼容性:
picker.pick_position返回的坐标和你构建模型时输入的DEM坐标完全对齐,不需要额外做坐标系转换即可直接使用 - 缩放适配:如果你构建地形时设置了
warp_scale不等于1,需要将返回的Z值除以warp_scale才能得到原始高程值 - 多模型适配:如果你场景里有多个3D对象,可以通过
picker.actor == surface的判断,只响应对地形模型的点击,忽略对其他模型的点击触发
内容的提问来源于stack exchange,提问作者Supriya Bhide
相关产品推荐
相关产品推荐

