【发布时间】:2014-08-27 20:20:59
【问题描述】:
我在一个简单的 WindowsFormsApplication 上使用带有 C# 的 ilnumerics,并在 ILPanel 上的 PlotCube 中创建了一些 LinePlot。喜欢在:
How to find the 3D coordinates of a surface from the click location of the mouse on the ILNumerics surface plots?
我试图在单击 PlotCube 时获取翻译后的坐标,以创建类似于 MATLAB 上的数据提示的内容。
我使用的是 ILLinePlot 而不是 ILSurface,我的 x 轴是对数刻度。
所以我将上面链接中提到的方法调整到我的设置中。
我的问题是,当我准确地点击 LinePlot 时,我只能得到正确的坐标!
当在 PlotCube 的行旁边或其他任何地方单击时,上面的 MouseClick 方法会遇到 NullReferenceException。
我对这个问题的想法是,如果我没有点击 LinePlot,则不要使用 MouseClick 目标来获取转换,而是将组设置为 LinePlot,就像我点击它一样(参见我的示例)。
但是,尽管我现在在 while 循环中得到相同的组并且没有异常调试表明 PlotsData 组和 PlotCubeScale 组的转换矩阵在两种情况下都不同。 如果我没有点击 LinePlot,所有的转换矩阵都只是身份。
下面是我的简短示例:
private void ilPanel1_Load(object sender, EventArgs e)
{
ILArray<double> A = new Double[,] {{1,4,0},{10,12,0},{100,10,0},{1000,18,0},{10000,15,0}};
var scene = new ILScene() {
new ILPlotCube(twoDMode: true){
new ILLinePlot(ILMath.tosingle(A))
}
};
scene.First<ILPlotCube>().ScaleModes.XAxisScale = AxisScale.Logarithmic;
scene.First<ILPlotCube>().MouseEnter += (_s, _a) =>
{
if (!_a.DirectionUp)
{
//onplot is a global flag which is true if the mouse is over the LinePlot
Text = "On Plot - Target: " + _a.Target.ToString();
onplot = true;
}
};
scene.First<ILPlotCube>().MouseLeave += (_s, _a) =>
{
if (!_a.DirectionUp)
{
Text = "Off Plot - Target: " + _a.Target.ToString();
onplot = false;
}
};
scene.First<ILPlotCube>().MouseClick += (s, arg) =>
{
if (!arg.DirectionUp)
return;
var group = arg.Target.Parent;
// *new part: group holds my LinePlot if I clicked on it
// else it holds the PlotCube
if (!onplot)
{
// so I search the LinePlot at set group to it
foreach (ILLineStrip strip in scene.Find<ILLineStrip>())
{
if (strip.Tag == "LinePlotLine")
{
group = strip.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;
// here I take care of the logarithmic scale of the xAxis
pos.X = (float)ILMath.pow(10.0, pos.X);
// view result in the window title
Text = "Model Position: " + pos.ToString();
}
}
};
ilPanel1.Scene = scene;
}
为什么 group.Transform-matrices 会根据我的点击位置而有所不同?两种情况下的while循环完全相同。
我希望任何人都能理解我的问题。尽管搜索了数周,但我没有找到任何答案或不同的方法来实现我的目标,即向用户显示他点击的线上的点坐标。
非常感谢您的任何帮助。
【问题讨论】:
-
部分答案可以在这里找到:ilnumerics.net/scene-management.html。它解释了恒等矩阵。此外,尝试将处理程序附加到 ILPlotcubeDatagroup 而不是 plotcube。它可能会进一步简化事情。有帮助吗?
-
非常感谢您的快速答复!我的 PlotCube 和 LinePlot 生活在我的全局场景的不同同步上,因此我得到不同的转换,我是否理解正确?!当我将处理程序附加到 ILPlotcubeDatagroup 而不是 plotcube 时,它们似乎只在我点击 LinePlot 时触发。这是期望的行为吗?所以这对我的 MouseClick 事件没有意义,对吧?!还是我误会了什么?
标签: c# ilnumerics