【C#-Helixtoolkit】HelixViewport3D绘制曲线

【C#-Helixtoolkit】HelixViewport3D绘制曲线_第1张图片

WPF-Helixtoolkit绘制螺旋路径

【C#-Helixtoolkit】HelixViewport3D绘制曲线_第2张图片WPF-helixtoolkit绘制3D曲线路径

【C#-Helixtoolkit】HelixViewport3D绘制曲线_第3张图片WinForm加载helixtoolkit

视频演示

部分代码:

一、绘制螺旋线

private void GatherData(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                //Thread.Sleep(5);  // 50ms数据采样周期


                // Generate a test trace: an upward spiral with square corners
                //生成一个测试轨迹:一个带有方角的向上螺旋线
                double t = stopwatch.Elapsed.TotalSeconds * 1;//* 0.25;
                double sint = Math.Sin(t);
                double cost = Math.Cos(t);
                double x, y, z = t * 0.5;
                Color color;


                if (sint > 0.0 && cost > 0.0)
                {
                    if (sint > cost)
                    {
                        x = 100.0;
                        y = 70.71 * cost + 50.0;
                    }
                    else
                    {
                        x = 70.71 * sint + 50.0;
                        y = 100.0;
                    }
                    color = Colors.Red;//红色
                }
                else if (sint < 0.0 && cost < 0.0)
                {
                    if (sint < cost)
                    {
                        x = 0.0;
                        y = 70.71 * cost + 50.0;
                    }
                    else
                    {
                        x = 70.71 * sint + 50.0;
                        y = 0.0;
                    }
                    color = Colors.Red;//红色
                }
                else
                {
                    x = 50.0 * sint + 50.0;
                    y = 50.0 * cost + 50.0;
                    color = Colors.Blue;//蓝色
                }


                var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);//创建新的自定义点
                bool invoke = false;
                lock (points)//锁定点集
                {
                    points.Add(point);//添加到点集
                    invoke = (points.Count == 1);//每新增一个点就开始回调绘制数据函数
                }


                if (invoke)//在System.Windows.Threading.Dispatcher关联的线程上以指定的优先级异步执行指定的委托。
                    Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)PlotData);
            }
        }
        //绘制数据
        private void PlotData()
        {
            if (points.Count == 1)
            {
                Point3DPlus point;
                lock (points)
                {
                    point = points[0];
                    points.Clear();
                }


                plot.AddPoint(point.point, point.color, point.thickness);//绘制单个点
            }
            else
            {
                Point3DPlus[] pointsArray;//点数组
                lock (points)//锁定点集
                {
                    pointsArray = points.ToArray();
                    points.Clear();
                }


                foreach (Point3DPlus point in pointsArray)
                    plot.AddPoint(point.point, point.color, point.thickness);//绘制轨迹
            }
        }

二、绘制3D曲线路径

private void GatherData(object sender, DoWorkEventArgs e)
        {
            var readDataStream = new System.IO.StreamReader(filePath, Encoding.UTF8);


            while (true)
            {
                Thread.Sleep(200);  // can use to change the poltting rat
                List points = new List();


                Color color = Colors.Black;
                double x = 0, y = 0, z = 0;


                const int addPointSum = 50; //can use to change the poltting rate


                for (int i = 0; i < addPointSum; i++)
                {
                    if (readDataStream.EndOfStream)
                    {
                        break;
                    }


                    var readDataLine = readDataStream.ReadLine();


                    var readDataNumbers = readDataLine.Split(' ');
                    //if (readDataNumbers.Count()==3)
                    {                   
                        try
                        {
                            x = Convert.ToDouble(readDataNumbers[0]);
                            y = Convert.ToDouble(readDataNumbers[1]);


                            if (readDataNumbers.Length >= 3)
                            {
                                z = Convert.ToDouble(readDataNumbers[2]);
                            }
                            else
                            {
                                z = 0;
                            }
                        }
                        catch
                        {
                            System.Windows.MessageBox.Show("Data format is error. The format is 'x y z'.", "Error", MessageBoxButton.OK,
                                MessageBoxImage.Error);
                            Environment.Exit(-1);
                        }
                    }
                    var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);


                    points.Add(point);
                }


                bool invoke = false;
                if (points.Count > 0)
                {
                    pointsList.Enqueue(points);//点集队列
                    invoke = true;
                }


                if (invoke)//执行更新显示
                {
                    Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)PlotData);
                }
            }
        }


        private void PlotData()
        {
            if (pointsList.Count > 0)
            {
                bool resultPop = pointsList.TryDequeue(out var points);//取出点集
                if (resultPop)
                {
                    var pointsArray = points.ToArray();


                    foreach (Point3DPlus point in pointsArray)
                        plot.AddPoint(point.point, point.color, point.thickness);//绘制
                }
            }
        }

三、WinForm加载Helixtoolkit控件

将WPF中上面示例的主窗体封装成WPF自定义控件public partial class MyControl : UserControl,之后引用并添加到winform窗体。缺点是不能实时刷新。等完全绘制完毕再更新显示。以下是自定义控件的HelixPlot数据显示方法。

public void GatherData()
        {
            List points = new List();
            for(int tick=0;tick<3660;tick++)
            {
               // Thread.Sleep(50);
                double t = (double)tick/60.0;
               // tick++;
                double sint = Math.Sin(t);
                double cost = Math.Cos(t);
                double x, y, z = t;
                Color color;


                x = 50.0 * sint + 50.0;
                y = 50.0 * cost + 50.0;
                if (flag)
                {
                    color = _graphcolor;
                    flag = false;
                }
                else
                {
                    flag = true;
                    color = _pausecolor;
                }


                var point = new Point3DPlus(new Point3D(x, y, z), color, 1.5);
                bool invoke = false;
                lock (points)
                {
                    points.Add(point);
                    invoke = (points.Count == 1);
                }


                if (invoke)
                {
                    Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)delegate () {
                        if (points.Count == 1)
                        {
                            Point3DPlus p;
                            lock (points)
                            {
                                p = points[0];
                                points.Clear();
                            }


                            plot.AddPoint(p.point, p.color, p.thickness);


                        }
                        else
                        {
                            Point3DPlus[] pointsArray;
                            lock (points)
                            {
                                pointsArray = points.ToArray();
                                points.Clear();
                            }


                            foreach (Point3DPlus pt in pointsArray)
                                plot.AddPoint(pt.point, pt.color, pt.thickness);


                        }
                    });
                }       
            }
        }

在winform中单击按钮绘制螺旋线:

private void btnDraw_Click(object sender, EventArgs e)
        {
            myControl1.BackgroundBrush = System.Windows.Media.Brushes.Black;
            myControl1.AxisBrush = System.Windows.Media.Brushes.White;
            myControl1.MarkerBrush = System.Windows.Media.Brushes.Yellow;
            myControl1.GraphColor = Colors.LightGreen;
            myControl1.PauseColor = Colors.Black;
            myControl1.Satellite = "USI";




            initBackground = myControl1.Background;
            initAxisBrush = myControl1.AxisBrush;
            initMarkerBrush = myControl1.MarkerBrush;
            initGraphColor = myControl1.GraphColor;
            initPauseColor = myControl1.PauseColor;
            initSatellite = myControl1.Satellite;
            myControl1.GatherData();
        }

参考:

https://www.codeproject.com/Articles/1246255/Plotting-a-Real-time-D-Toolpath-with-Helix-Toolkit

https://gitee.com/mirrors/Helix-Toolkit

https://github.com/helix-toolkit/helix-toolkit/issues/1341

The End

你可能感兴趣的:(.net,winform,wpf,angularjs,webview)