目前,我们的系统使用 ILNumerics 3D 绘图立方体类和 ILNumerics 曲面组件来显示 3D 网格曲面。我们系统的目标是能够通过鼠标单击绘图来询问表面上的各个点。我们在绘图上设置了 MouseClick 事件,问题是我不确定如何获取已单击的表面上特定点的值,有人可以帮助解决这个问题吗?
从 2D 鼠标坐标到 3D“模型”坐标的转换是可能的 - 在某些限制下:
这种转换并不明确。鼠标事件仅提供 2 个维度:X 和 Y 屏幕坐标。在 3D 模型中,该 2D 屏幕点“后面”可能有多个点。因此,最好的方法是计算 3D 中的一条线,从相机开始,到无限深度结束。
虽然理论上至少可以尝试找到线与 3D 对象的交叉点,但 ILNumerics 目前还不能。即使在简单的表面情况下,也可以轻松构建在多个点交叉的 3D 模型。
-
对于简化的情况,存在一种解决方案:如果 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(使用前将#替换为@)