iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >WPF怎么实现雷达扫描图的绘制
  • 194
分享到

WPF怎么实现雷达扫描图的绘制

2023-06-30 12:06:02 194人浏览 独家记忆
摘要

这篇文章主要介绍了WPF怎么实现雷达扫描图的绘制的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇WPF怎么实现雷达扫描图的绘制文章都会有所收获,下面我们一起来看看吧。制作思路绘制圆形(或者称之轮)绘制分割线绘制扫

这篇文章主要介绍了WPF怎么实现雷达扫描图的绘制的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇WPF怎么实现雷达扫描图的绘制文章都会有所收获,下面我们一起来看看吧。

制作思路

  • 绘制圆形(或者称之轮)

  • 绘制分割线

  • 绘制扫描范围

  • 添加扫描点

具体实现

首先我们使用自定义的控件。你可以使用vs自动添加,也可以手动创建类。注意手动创建时要创建Themes/Generic.xaml的文件路径哦。

控件继承自itemscontrol,取名叫做Radar。

我们第一步思考如何实现圆形或者轮,特别是等距的轮。

我们可以使用简单的itemscontrol的WPF控件,通过自定义ItemTemplate就可以简单的创建了。

因为要显示圆,所以使用Ellipse是最简单的事情。

又因为要在同一个区域内,显示同心圆,我们将面板改为Grid,利用叠加的特性去构造同心圆。

既然我们用了itemscontrol 来承载圈轮,直接让这个圈可自定义呢?

所以,我们构造一个集合依赖属性。

/// <summary>        /// 每圈的大小        /// </summary>        public FreezableCollection<RadarSize> RadarCircle        {            get { return (FreezableCollection<RadarSize>)GetValue(RadarCircleProperty); }            set { SetValue(RadarCircleProperty, value); }        }        /// <summary>        /// 每圈的大小        /// </summary>        public static readonly DependencyProperty RadarCircleProperty =            DependencyProperty.ReGISter("RadarCircle", typeof(FreezableCollection<RadarSize>), typeof(Radar), new PropertyMetadata(new PropertyChangedCallback(OnRadarCircelValueChanged)));

对应泛型类可以参考源代码,基本元素就是绑定ellipse的参数

<ItemsControl Grid.ColumnSpan="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="ic"  ItemsSource="{TemplateBinding RadarCircle }">                            <ItemsControl.ItemsPanel>                                <ItemsPanelTemplate>                                    <Grid IsItemsHost="True"/>                                </ItemsPanelTemplate>                            </ItemsControl.ItemsPanel>                            <ItemsControl.ItemTemplate>                                <DataTemplate>                                    <Ellipse Width="{Binding  Width}" Height="{Binding Height}"  Stroke="{Binding Color}"/>                                </DataTemplate>                            </ItemsControl.ItemTemplate>    </ItemsControl>

哇啦,图像就出来了。

WPF怎么实现雷达扫描图的绘制

同理,我们创建分割线也是同样的过程。

对于分割线的切割算法,我们使用圆上点的坐标可以通过( rcos,rsin)=》(x,y) ,也就是极坐标。

关于此部分代码是放在布局块内ArrangeOverride,也可以放置在OnReader。

下面是局部代码,完整可以参考源代码

var angle = 180.0 / 6;            circlesize = size.Height > size.Width ? size.Width : size.Height;            RadarFillWidth = circlesize;            var midx = circlesize / 2.0;            var midy = circlesize / 2.0;            circlesize = circlesize / 2;            RadarRadius = circlesize;            //默认为6个            for (int i = 0; i < 6; i++)            {                var baseangel = angle * i;                var l1 = new Point(midx + circlesize * Math.Cos(Rad(baseangel)), midy - circlesize * Math.Sin(Rad(baseangel)));                var half = baseangel + 180;                var l2 = new Point(midx + circlesize * Math.Cos(Rad(half)), midy - circlesize * Math.Sin(Rad(half)));                RadarLineSize radarLine = new RadarLineSize();                radarLine.Start = l1;                radarLine.End = l2;                radarLine.Color = RadarLineColor;                RadarLine.Add(radarLine);            }            return size;

依赖属性

/// <summary>        /// 雷达图的分割线,目前固定为6,可以自行修改        /// </summary>        public FreezableCollection<RadarLineSize> RadarLine        {            get { return (FreezableCollection<RadarLineSize>)GetValue(RadarLineProperty); }            set { SetValue(RadarLineProperty, value); }        }        /// <summary>        /// 雷达图的分割线,目前固定为6,可以自行修改        /// </summary>        public static readonly DependencyProperty RadarLineProperty =            DependencyProperty.Register("RadarLine", typeof(FreezableCollection<RadarLineSize>), typeof(Radar));

xaml代码

<ItemsControl Grid.ColumnSpan="2" Grid.RowSpan="2"  VerticalAlignment="Center" HorizontalAlignment="Center"  x:Name="ic2"   ItemsSource="{TemplateBinding RadarLine }">                            <ItemsControl.ItemsPanel>                                <ItemsPanelTemplate>                                    <Grid IsItemsHost="True"/>                                </ItemsPanelTemplate>                            </ItemsControl.ItemsPanel>                            <ItemsControl.ItemTemplate>                                <DataTemplate>                                    <Line X1="{Binding Start.X}" Y1="{Binding Start.Y}" X2="{Binding End.X}" Y2="{Binding End.Y}"  Stroke="{Binding Color}"/>                                </DataTemplate>                            </ItemsControl.ItemTemplate>                        </ItemsControl>

WPF怎么实现雷达扫描图的绘制

下一步就是扇形扫描了。

我们使用一个完整的圆,将其内部颜色填充为线性刷就可以得到一个效果不错的扫描了。

/// <summary>        /// 雷达扫描的颜色        /// </summary>        public Brush RadarColor        {            get { return (Brush)GetValue(RadarColorProperty); }            set { SetValue(RadarColorProperty, value); }        }        /// <summary>        /// 雷达扫描的颜色        /// </summary>        public static readonly DependencyProperty RadarColorProperty =            DependencyProperty.Register("RadarColor", typeof(Brush), typeof(Radar));

为了更好的定义这个圆,我们将radar的template使用grid面板等距分成四个区域(其实没啥用,主要是为了扇形扫描时做圆心选择的line,也可以不分成四个)。

在考虑动画,只需要做圆形360的选择就可以了。为了更好应用,我们创一个paly的依赖属性来播放动画。

/// <summary>        /// 是否播放动画        /// </summary>        public bool Play        {            get { return (bool)GetValue(PlayProperty); }            set { SetValue(PlayProperty, value); }        }        /// <summary>        /// 是否播放动画        /// </summary>        public static readonly DependencyProperty PlayProperty =            DependencyProperty.Register("Play", typeof(bool), typeof(Radar), new PropertyMetadata(false));

xaml代码( 部分)

<Style.Resources>            <LinearGradientBrush x:Key="radarcolor" StartPoint="0,0" EndPoint="0,1">                <GradientStop Offset="0" Color="Lime" />                <GradientStop Offset="0.5" Color="Transparent" />            </LinearGradientBrush>        </Style.Resources>  <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="{x:Type local:Radar}">                    <Grid x:Name="grid"   >                        <Grid.RowDefinitions>                            <RowDefinition Height="2*"/>                            <RowDefinition Height="2*"/>                        </Grid.RowDefinitions>                        <Grid.ColumnDefinitions>                            <ColumnDefinition Width="2*"/>                            <ColumnDefinition Width="2*"/>                        </Grid.ColumnDefinitions>                        <ItemsControl Grid.ColumnSpan="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="ic"  ItemsSource="{TemplateBinding RadarCircle }">                            <ItemsControl.ItemsPanel>                                <ItemsPanelTemplate>                                    <Grid IsItemsHost="True"/>                                </ItemsPanelTemplate>                            </ItemsControl.ItemsPanel>                            <ItemsControl.ItemTemplate>                                <DataTemplate>                                    <Ellipse Width="{Binding  Width}" Height="{Binding Height}"  Stroke="{Binding Color}"/>                                </DataTemplate>                            </ItemsControl.ItemTemplate>                        </ItemsControl>                        <ItemsControl Grid.ColumnSpan="2" Grid.RowSpan="2"  VerticalAlignment="Center" HorizontalAlignment="Center"  x:Name="ic2"   ItemsSource="{TemplateBinding RadarLine }">                            <ItemsControl.ItemsPanel>                                <ItemsPanelTemplate>                                    <Grid IsItemsHost="True"/>                                </ItemsPanelTemplate>                            </ItemsControl.ItemsPanel>                            <ItemsControl.ItemTemplate>                                <DataTemplate>                                    <Line X1="{Binding Start.X}" Y1="{Binding Start.Y}" X2="{Binding End.X}" Y2="{Binding End.Y}"  Stroke="{Binding Color}"/>                                </DataTemplate>                            </ItemsControl.ItemTemplate>                        </ItemsControl>                        <Ellipse Fill="{TemplateBinding RadarColor}"   Grid.ColumnSpan="2" Grid.RowSpan="2"  x:Name="ep" RenderTransfORMOrigin="0.5,0.5" Width="{TemplateBinding RadarFillWidth}" Height="{TemplateBinding RadarFillWidth}">                            <Ellipse.RenderTransform>                                <RotateTransform x:Name="rtf" />                            </Ellipse.RenderTransform>                        </Ellipse>                    </Grid>                    <ControlTemplate.Triggers>                        <Trigger Property="Play" Value="True">                            <Trigger.EnterActions>                                <BeginStoryboard  x:Name="bs" >                                    <Storyboard >                                        <DoubleAnimation Storyboard.TargetName="rtf" Storyboard.TargetProperty="Angle"   From="0" To="360" Duration="0:0:2" RepeatBehavior="Forever"/>                                    </Storyboard>                                </BeginStoryboard>                            </Trigger.EnterActions>                        </Trigger>                        <Trigger Property="Play" Value="False">                            <Trigger.EnterActions>                                <RemoveStoryboard BeginStoryboardName="bs"/>                            </Trigger.EnterActions>                        </Trigger>                    </ControlTemplate.Triggers>                </ControlTemplate>            </Setter.Value>

效果

WPF怎么实现雷达扫描图的绘制

那么剩下就是扫描点的操作。

因为我们的控件是继承ItemsControl,我们到现在还没有利用ItemsSource这个属性。

所以我们要制作一个子控件来呈现扫描点。

由于子控件较为简单,只不过是一个圆而已。我们就让子控件继承Control就好了。

一切从简,我们不弄布局这一套了,直接在父控件中使用canvas面板,子控件增加属性Left,Top这两个依赖属性。

重点说一下,子控件中存在一个linscar的方法,是为了将点如果在雷达外侧时,按照同角度缩放到最外层的方法。就是通过半径重新计算一边极坐标。

/// <summary>        /// 线性缩放        /// </summary>        /// <param name="size">半径</param>        internal void LineScar(double size)        {            var midpoint = new Vector(size, size);            var vp = new Vector(Left, Top);            var sub = vp - midpoint;            var angle = Vector.AngleBetween(sub, new Vector(size, 1));            angle = angle > 0 ? angle : angle + 360;            //距离大于半径,根据半径重新绘制            if (sub.Length >= size)            {                Top = size - size * Math.Sin(Rad(angle)) - Width / 2;                Left = size + size * Math.Cos(Rad(angle)) - Width / 2;            }        }

那么在父项中如何摆放呢?

我们刚才说父项使用canvas绘图,所以我们在radar中修改itempanel的面板属性,下面代码存在于父项xaml

<Setter Property="ItemsPanel">            <Setter.Value>                <ItemsPanelTemplate>                    <Canvas IsItemsHost="True"/>                </ItemsPanelTemplate>            </Setter.Value>        </Setter>

子项代码如下,比较少就贴了

xaml代码

<Style TargetType="local:RadarItem">        <Setter Property="VerticalAlignment" Value="Top" />        <Setter Property="HorizontalAlignment" Value="Left" />        <Setter Property="Padding" Value="0" />        <Setter Property="Margin" Value="0" />        <Setter Property="Canvas.Top" Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=Top}" />        <Setter Property="Canvas.Left" Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=Left}" />        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="local:RadarItem">                    <Border  >                        <Ellipse Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="{TemplateBinding Color}" />                    </Border>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style>

radarItem

/// <summary>    /// 雷达子项     /// </summary>    public class RadarItem : Control    {        static RadarItem()        {            DefaultStyleKeyProperty.OverrideMetadata(typeof(RadarItem), new FrameworkPropertyMetadata(typeof(RadarItem)));        }        public RadarItem()        {        }        /// <summary>        /// 转弧度        /// </summary>        /// <param name="val">角度</param>        /// <returns>弧度制</returns>        double Rad(double val)        {            return val * Math.PI / 180;        }        /// <summary>        /// 线性缩放        /// </summary>        /// <param name="size">半径</param>        internal void LineScar(double size)        {            var midpoint = new Vector(size, size);            var vp = new Vector(Left, Top);            var sub = vp - midpoint;            var angle = Vector.AngleBetween(sub, new Vector(size, 1));            angle = angle > 0 ? angle : angle + 360;            //距离大于半径,根据半径重新绘制            if (sub.Length >= size)            {                Top = size - size * Math.Sin(Rad(angle)) - Width / 2;                Left = size + size * Math.Cos(Rad(angle)) - Width / 2;            }        }        /// <summary>        /// 顶部距离,用canvas.top绘制        /// </summary>        public double Top        {            get { return (double)GetValue(TopProperty); }            set { SetValue(TopProperty, value); }        }        /// <summary>        /// 顶部距离,用canvas.top绘制        /// </summary>        public static readonly DependencyProperty TopProperty =            DependencyProperty.Register("Top", typeof(double), typeof(RadarItem), new PropertyMetadata(0.0));        /// <summary>        /// 左侧距离,用于canvas.left绘制        /// </summary>        public double Left        {            get { return (double)GetValue(LeftProperty); }            set { SetValue(LeftProperty, value); }        }        /// <summary>        /// 左侧距离,用于canvas.left绘制        /// </summary>        public static readonly DependencyProperty LeftProperty =            DependencyProperty.Register("Left", typeof(double), typeof(RadarItem), new PropertyMetadata(0.0));        /// <summary>        /// 填充颜色        /// </summary>        public Brush Color        {            get { return (Brush)GetValue(ColorProperty); }            set { SetValue(ColorProperty, value); }        }        /// <summary>        /// 填充颜色        /// </summary>        public static readonly DependencyProperty ColorProperty =            DependencyProperty.Register("Color", typeof(Brush), typeof(RadarItem), new PropertyMetadata(new SolidColorBrush(Colors.Red)));    }

于是乎我们就得到了一个雷达扫描图

WPF怎么实现雷达扫描图的绘制

关于“WPF怎么实现雷达扫描图的绘制”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“WPF怎么实现雷达扫描图的绘制”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: WPF怎么实现雷达扫描图的绘制

本文链接: https://www.lsjlt.com/news/328822.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • WPF怎么实现雷达扫描图的绘制
    这篇文章主要介绍了WPF怎么实现雷达扫描图的绘制的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇WPF怎么实现雷达扫描图的绘制文章都会有所收获,下面我们一起来看看吧。制作思路绘制圆形(或者称之轮)绘制分割线绘制扫...
    99+
    2023-06-30
  • WPF实现雷达扫描图的绘制详解
    目录前言制作思路具体实现前言 实现一个雷达扫描图。 源代码在TK_King/雷达 (gitee.com),自行下载就好了 制作思路 绘制圆形(或者称之轮)绘制分割线绘制扫描范围添加...
    99+
    2024-04-02
  • 怎么用Qt绘制雷达扫描效果
    本文小编为大家详细介绍“怎么用Qt绘制雷达扫描效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Qt绘制雷达扫描效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。scan.h的代码如下#ifndef&nb...
    99+
    2023-07-05
  • CSS3如何实现雷达扫描图
    这篇文章给大家分享的是有关CSS3如何实现雷达扫描图的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。通过css3实现炫酷的雷达扫描图:直接上代码:// index.html<!DOCTYPE&nbs...
    99+
    2023-06-08
  • 利用Qt绘制雷达扫描效果
    话不多说直接上代码,代码规范性可能差了点,但是效果得以实现,在这里记录一下。 scan.h的代码如下 #ifndef SCAN_H #define SCAN_H #include ...
    99+
    2023-05-14
    Qt实现雷达扫描效果 Qt雷达扫描 Qt雷达
  • Matlab实现绘制雷达图(蜘蛛图)
    目录绘制效果教程部分基础绘制改变样式添加修改标签添加图例R轴位置及其范围修改轴属性修改标签属性修改圆形背景修饰多边形工具函数完整代码绘制效果 教程部分 基础绘制 数据为数值矩阵即...
    99+
    2024-04-02
  • 怎么使用python绘制雷达图
    这篇文章主要介绍了怎么使用python绘制雷达图,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。python有哪些常用库python常用的库:1.requesuts;2.scr...
    99+
    2023-06-14
  • Python怎么使用pyecharts绘制雷达图
    本篇内容介绍了“Python怎么使用pyecharts绘制雷达图”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!雷达图雷达图是以从同一点开始的...
    99+
    2023-07-02
  • Android仿微信雷达扫描效果的实现方法
    本文主要给大家介绍的是关于Android实现微信雷达扫描效果的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:废话不多说 先上图(用AS录制的 转换工具不是很好 所以看得效果不是很好)效果图示例代码Activity 代码public...
    99+
    2023-05-31
    android 雷达扫描
  • WPF仿LiveCharts实现饼图的绘制
    目录前言 一、PieControl.cs二、App.xaml三、MainWindow.xaml四、MainWindow.xaml.cs每日一笑 下班和实习生一起回家,公交站...
    99+
    2024-04-02
  • WPF如何实现绘制3D图形
    今天小编给大家分享一下WPF如何实现绘制3D图形的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。关键概念视口视口指的是图像要展...
    99+
    2023-07-05
  • WPF实现雷达图(仿英雄联盟)的示例代码
    目录前言实现代码效果预览前言 有小伙伴提出需要实现雷达图。    由于在WPF中没有现成的雷达图控件,所以我们自己实现一个。 PS:有更好的方式欢迎推荐。 实现...
    99+
    2024-04-02
  • WPF+ASP.NETSignalR实现动态折线图的绘制
    目录什么是SignalRSignalR做了什么封装与集成SignalR用途官方网址和源码示例截图服务端项目创建SignalR服务端业务集成SignalR服务端配置客户端项目创建客户端...
    99+
    2023-01-03
    WPF 动态折线图 WPF 折线图 WPF SignalR 折线图
  • Python绘制雷达图时遇到的坑的解决
    ValueError: The number of FixedLocator locations (9), usually from a call to set_ticks, do...
    99+
    2024-04-02
  • Java实现简单的扫雷图
    用Java实现简单的扫雷图,供大家参考,具体内容如下 扫雷图的思想是: 1、地图可以是一个二维数组,并对数组进行初始化 2、随机生成雷的位置,可以用Random函数进行随机生成也...
    99+
    2024-04-02
  • WPF实现绘制3D图形的示例代码
    目录关键概念视口相机光源材质3D对象命中测试(鼠标交互)3D对象中2D控件渲染外部导入3D模型WPF的3D功能可以在不编写任何c#代码的情况下进行绘制,只需要使用xaml即可完成3D...
    99+
    2023-03-02
    WPF绘制3D图形 WPF 3D图形 WPF 3D
  • WPF+WriteableBitmap实现高性能曲线图的绘制
    目录一、前言二、正文三、运行效果一、前言 之前分享过一期关于DrawingVisual来绘制高性能曲线的博客,今天再分享一篇通过另一种方式来绘制高性能曲线的方法,也就是通过Write...
    99+
    2022-11-13
    WPF WriteableBitmap绘制曲线图 WPF WriteableBitmap 曲线图 WPF WriteableBitmap
  • WPF实现绘制统计图(柱状图)的方法详解
    目录前言实现代码效果预览前言 有小伙伴提出需要实现统计图。  由于在WPF中没有现成的统计图控件,所以我们自己实现一个。 PS:有更好的方式欢迎推荐。 实现代码 一、创建...
    99+
    2024-04-02
  • WPF怎么使用DrawingContext实现二维绘图
    这篇文章主要介绍“WPF怎么使用DrawingContext实现二维绘图”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“WPF怎么使用DrawingContext实现二维绘图”文章能帮助大家解决问题。...
    99+
    2023-07-02
  • WPF实现绘制扇形统计图的示例代码
    扇形统计图 绘制一个扇形原理也是基于Canvas进行绘制;ArcSegment[1]绘制弧形;绘制指示线;绘制文本;鼠标移入动画;显示详情Popup;源码Github[2] ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作