簡體   English   中英

ILNumerics:使用ILLinePlot獲取鼠標坐標

[英]ILNumerics: Get mouse coordinates with ILLinePlot

我在一個簡單的WindowsFormsApplication上使用C#字母數字,並在ILPanel的PlotCube中創建了一些LinePlot。 像:
如何從ILNumerics曲面圖上的鼠標單擊位置中找到曲面的3D坐標?
我試圖在單擊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循環完全相同。

我希望任何人都能理解我的問題。 盡管搜索了數周,但我沒有找到任何答案或達到目標的其他方法,這只是向用戶顯示他單擊的直線上的點的坐標。

非常感謝您的幫助。

一種解決方法是從鼠標處理程序的目標而不是直接從場景獲取線圖節點。 這樣,我們始終可以獲得正確的轉換。 用以下內容替換識別線圖的邏輯

 ILGroup plotcubeGroup = e.Target as ILGroup;
 ILGroup group = plotcubeGroup.Children.Where(item => item.Tag == "LinePlot").First() as ILGroup;
 if(group != null)
    {
    // continue with same logic as above
    }

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM