I'm using ilnumerics with C# on a simple WindowsFormsApplication and created some LinePlots in a PlotCube on an ILPanel. Like in:
How to find the 3D coordinates of a surface from the click location of the mouse on the ILNumerics surface plots?
i tried to get the translated coordinates while clicking into the PlotCube to create something similar to the data tips at MATLAB.
Instead of a ILSurface I'm using ILLinePlot and my x-Axis is of logarithmic scale.
So I adapted the method mentioned at the above link to my setting.
My problem is that I only get correct coordinates when i am clicking exactly at the LinePlot!
When clicking right next to the line or anywhere else at the PlotCube the above MouseClick method runs into a NullReferenceException.
My idea for that problem was not to use the MouseClick target to get the transformations if i didn't hit the LinePlot but to set the group to the LinePlot like as if I had clicked on it (see at my example).
But although I now get the same groups in the while-loop and no Exception debugging shows that the transformation matrices of the PlotsData group and the PlotCubeScale group differ in both cases. If I don't hit the LinePlot all transformation matrices are just the identities.
Here comes my short example:
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;
}
Why do the group.Transform-matrices differ depending on my clicking position? The while-loop is exactly the same in both cases.
I hope that anyone can understand my problem. Although searching for weeks I didn't find any answer or different ways to reach my goal which is just to show the user the Coordinates of the Points on the line where he is clicking.
Thank you very much in advance for any help.