天天看點

WPF特效-繪制實時2D雷射雷達圖

原文: WPF特效-繪制實時2D雷射雷達圖 接前兩篇: https://blog.csdn.net/u013224722/article/details/80738619 https://blog.csdn.net/u013224722/article/details/80738995

除了c# GDI 、Opencv(c++)、 c# Emgu繪圖外,其實c#  WPF繪圖功能也很強大。上文中之是以最終使用了Emgu繪圖 ,隻是因為在踩坑過程中嘗試使用了Emgu的圖像處理函數。 即首先将List<double>的資料集合處理成DrawingImage然後得到RenderTargetBitmap,再轉換為System.Drawing.Bitmap 再轉換為Emgu.CV.Image。 是以後續的實驗中直接就使用了Emgu繪圖,處理完成後轉換為BitmapSource在WPF界面呈現。其實完全使用WPF的繪圖方式也能實作實時雷達圖效果。

如:

WPF特效-繪制實時2D雷射雷達圖
繪制效率也挺不錯的。上面的Gif,每秒10幀,每幀760個資料點。  顯示成弧形是因為我将資料截斷了,即設定了最大值範圍,超過了則等于設定的最大值。

#region Data Processing

        private DrawingGroup DrawingGroup;

        private void InitRadarVisualDraw()
        {
            this.DrawingGroup = new DrawingGroup();
            DrawingImage oImgSrc = new DrawingImage(this.DrawingGroup);
            this.ImgMainZm.Source = oImgSrc;

            this.ImgMainZm.Height = this.RadarRadius;
            this.ImgMainZm.Width = this.RadarRadius * 1920d / 1080d;
            this.IntervalDegree = 240d / 760d;
        }

        private double RadarRadius = 1000d;
        private double IntervalDegree = 0;

        private void DrawRadarDatas(List<double> ltDistances)
        {
            try
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
                {
                    using (DrawingContext oDrawContent = this.DrawingGroup.Open())
                    {
                        oDrawContent.DrawRectangle(new SolidColorBrush(Colors.Black), new Pen(),
                            new Rect(0, 0, this.ImgMainZm.Width, this.ImgMainZm.Height));
                        oDrawContent.DrawEllipse(new SolidColorBrush(Colors.Green), new Pen(),
                               new Point(this.ImgMainZm.Width/2d, this.ImgMainZm.Height-10), 10, 10);
                        for (int i = 0; i < ltDistances.Count; i++)
                        {
                            double lDistance = ltDistances[i];
                            double dDegree = -120d + i * this.IntervalDegree;
                            double dRadian = Utilitys.ConvertToRads(dDegree);
                            double dX = this.ImgMainZm.Width / 2d + lDistance * Math.Sin(dRadian);
                            if (dX < 0)
                                dX = 0;
                            if (dX > this.ImgMainZm.Width)
                                dX = this.ImgMainZm.Width;
                            double dY = lDistance * Math.Cos(dRadian);

                            oDrawContent.DrawEllipse(new SolidColorBrush(Colors.Green), new Pen(),
                                new Point(dX, dY), 3, 3);
                        }
                    }
                }));
               
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        #endregion           

繼續閱讀