目前,我们的系统使用带有ILNumerics曲面组件的ILNumerics 3D绘图立方体类来显示3D网格曲面。我们系统的目标是通过鼠标点击图表来查询表面上的各个点。我们在我们的情节上设置了MouseClick事件问题是我不确定如何获取已被点击的表面上的特定点的值,是否有人可以帮助解决此问题?
答案 0 :(得分:1)
从2D鼠标坐标到3D'模型'坐标的转换是可能的 - 在某些限制下:
转换并非明确。鼠标事件仅提供2个维度:X和Y屏幕坐标。在3D模型中,此2D屏幕点可能不止一个点。因此,您可以获得的最佳效果是在3D中计算一条线,从相机开始并以无限深度结束。
虽然理论上至少可以尝试找到线与3D对象的交叉,但ILNumerics目前却没有。即使在表面的简单情况下,也很容易构建在多于一个点处穿过该线的3D模型。
对于简化的情况,存在一个解决方案:如果3D中的Z坐标无关紧要,可以使用常见的矩阵转换以获取3D中的X和Y坐标并仅使用这些坐标。比方说,你的情节是2D线图或表面图 - 但只是观察 '上方'(即未旋转的X-Y平面)。点击的点的Z坐标可能不感兴趣。让我们进一步假设,您已经在具有ILPanel的常见Windows应用程序中设置了ILScene场景:
private void ilPanel1_Load(object sender,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位置 - 必须反过来。在该示例中,我们获取每个组节点的变换矩阵,将它们全部相乘并且反转得到的变换矩阵。这是必需的,因为这种转换自然地描述了从子节点到父节点的转换。在这里,我们需要反过来 - 因此反转是必要的。
此方法在鼠标位置提供正确的3D坐标。但是,请记住这些限制!在这里,我们没有考虑绘图立方体的任何旋转(绘图立方体必须保持不旋转)并且没有投影变换(绘图立方体默认使用正交变换,这基本上是一个noop)。为了识别这些变量,您可以相应地扩展示例。