如何从 ILNumerics 曲面图上鼠标的单击位置找到曲面的 3D 坐标?

2023-12-14

目前,我们的系统使用 ILNumerics 3D 绘图立方体类和 ILNumerics 曲面组件来显示 3D 网格曲面。我们系统的目标是能够通过鼠标单击绘图来询问表面上的各个点。我们在绘图上设置了 MouseClick 事件,问题是我不确定如何获取已单击的表面上特定点的值,有人可以帮助解决这个问题吗?


从 2D 鼠标坐标到 3D“模型”坐标的转换是可能的 - 在某些限制下:

  1. 这种转换并不明确。鼠标事件仅提供 2 个维度:X 和 Y 屏幕坐标。在 3D 模型中,该 2D 屏幕点“后面”可能有多个点。因此,最好的方法是计算 3D 中的一条线,从相机开始,到无限深度结束。

  2. 虽然理论上至少可以尝试找到线与 3D 对象的交叉点,但 ILNumerics 目前还不能。即使在简单的表面情况下,也可以轻松构建在多个点交叉的 3D 模型。

  3. 对于简化的情况,存在一种解决方案:如果 3D 中的 Z 坐标并不重要,则可以使用常见的矩阵转换来获取 3D 中的 X 和 Y 坐标并仅使用它们。比方说,你的图是二维线图或曲面图 - 但只能从 “上方”(即未旋转的 X-Y 平面)。单击的点的 Z 坐标可能不重要。我们进一步假设,您已经使用 ILPanel 在常见的 Windows 应用程序中设置了 ILScene 场景:

    私人无效 ilPanel1_Load(对象发送者,EventArgs e){

    var scene  = new ILScene() {
        new ILPlotCube(twoDMode: true) {
            new ILSurface(ILSpecialData.sincf(20,30)) 
        }
    }; 
    scene.First<ILSurface>().MouseClick += (s,arg) => {
        // we start at the mouse event target -> this will be the 
        // surface group node (the parent of "Fill" and "Wireframe")
        var group = arg.Target.Parent;
        if (group != null) {
            // walk up to the next camera node 
            Matrix4 trans = group.Transform; 
            while (!(group is ILCamera) && group != null) {
                group = group.Parent;
                // collect all nodes on the path up
                trans = group.Transform * trans; 
            }
            if (group != null && (group is ILCamera)) {
                // convert args.LocationF to world coords
                // The Z coord is not provided by the mouse! -> choose arbitrary value
                var pos = new Vector3(arg.LocationF.X * 2 - 1, arg.LocationF.Y * -2 + 1, 0); 
                // invert the matrix.
                trans = Matrix4.Invert(trans); 
                // trans now converts from the world coord system (at the camera) to 
                // the local coord system in the 'target' group node (surface). 
                // In order to transform the mouse (viewport) position, we 
                // left multiply the transformation matrix.
                pos = trans * pos; 
                // view result in the window title
                Text = "Model Position: " + pos.ToString(); 
            }
        }
    };
    ilPanel1.Scene = scene; 
    

    }

它的作用:它在表面组节点上注册一个 MouseClick 事件处理程序。在处理程序中,它在从单击的目标(表面组节点)到表面所属的下一个相机节点的路径上累积变换矩阵。渲染时,顶点的(模型)坐标由每个组节点中托管的本地坐标变换矩阵进行变换。所有变换都会累积,因此顶点坐标最终位于由每个相机建立的“世界坐标”系统中。因此渲染从 3D 模型顶点位置找到 2D 屏幕位置。

为了从 2D 屏幕坐标找到 3D 位置 - 必须采取相反的方法。在示例中,我们获取每个组节点的变换矩阵,将它们全部相乘,然后invert得到的变换矩阵。这是必要的,因为这样的转换自然地描述了从子节点到父节点的转换。在这里,我们需要相反的方式 - 因此反转是必要的。

此方法给出鼠标位置的正确 3D 坐标。但是,请记住限制!在这里,我们不考虑绘图立方体的任何旋转(绘图立方体必须保持不旋转),并且不考虑投影变换(绘图立方体默认使用正交变换,这基本上是一个空操作)。为了也识别这些变量,您可以相应地扩展示例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 ILNumerics 曲面图上鼠标的单击位置找到曲面的 3D 坐标? 的相关文章

随机推荐