如何在 WPF 中使用 Circle 绘制相机的视野?

马尼什耆那教

我正在尝试使用 WPF 绘制圆弧,但不知何故我无法弄清楚如何执行此操作。我已经搜索了很多并通过了 WPF 的 Path 属性,但我发现这对我来说还不够好。我的要求是在 wpf 上显示闭路电视摄像机的视野。

用户有以下输入: 1. 圆的中心点。2. 圆的半径。3.角度(0-360)

我想让用户绘制一个圆形或一个完整的圆形区域,并且可以通过改变角度和半径来改变该区域。注意: 1. 中心是画布上的一个固定位置。2. 用户可以动态改变图形(区域)。

假设用户将提供 45 度角,那么圆将如下图所示: 在此处输入图片说明

布拉德利·乌夫纳

在我的旧代数教科书中度过了一段美好的时光后,我为您提供了一个完整的解决方案。

这使用WpfLib Nuget 包(免责声明:我是该包的作者)作为INotifyPropertyChanged支持,但您应该能够轻松更改您想要的任何更改事件系统。完整的解决方案可以从BitBucket下载

在此处输入图片说明

XAML:

<Window
    x:Class="ViewingAngle.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:ViewingAngle"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="525"
    Height="350"
    d:DataContext="{d:DesignInstance local:MainWindowVm}"
    mc:Ignorable="d">
    <DockPanel Margin="4">
        <StackPanel DockPanel.Dock="Bottom">
            <TextBlock Margin="4,4,4,0" Text="{Binding Path=FieldOfView, StringFormat='Field of View: {0}'}" />
            <Slider
                Margin="4"
                Maximum="360"
                Minimum="0"
                TickFrequency="5"
                TickPlacement="Both"
                Value="{Binding Path=FieldOfView}" />
            <TextBlock Margin="4,4,4,0" Text="{Binding Path=TargetAngle, StringFormat='Target Angle: {0}'}" />
            <Slider
                Margin="4"
                Maximum="360"
                Minimum="0"
                TickFrequency="5"
                TickPlacement="Both"
                Value="{Binding Path=TargetAngle}" />
        </StackPanel>

        <Viewbox Margin="4" Stretch="Uniform">
            <Canvas Width="500" Height="500">
                <Path
                    Fill="Blue"
                    Stroke="Blue"
                    StrokeThickness="1">
                    <Path.Data>
                        <PathGeometry>
                            <PathGeometry.Figures>
                                <PathFigure StartPoint="250,250">
                                    <LineSegment Point="{Binding Path=StartPoint}" />
                                    <ArcSegment
                                        IsLargeArc="{Binding Path=IsLargeArc}"
                                        Point="{Binding Path=EndPoint}"
                                        Size="250,250"
                                        SweepDirection="Clockwise" />
                                    <LineSegment Point="250,250" />
                                </PathFigure>
                            </PathGeometry.Figures>
                        </PathGeometry>
                    </Path.Data>
                </Path>
            </Canvas>
        </Viewbox>
    </DockPanel>
</Window>

视图模型:

using System;
using System.Windows;
using AgentOctal.WpfLib;

namespace ViewingAngle
{
    class MainWindowVm : ViewModel
    {
        private const int Radius = 250;
        private const int CenterX = 250;
        private const int CenterY = 250;


        public MainWindowVm()
        {
            FieldOfView = 45;
            TargetAngle = 90;
        }

        private int _fieldOfView;
        public int FieldOfView
        {
            get { return _fieldOfView; }
            set
            {
                SetValue(ref _fieldOfView, value);
                RecalculateArc();
            }
        }

        private int _targetAngle;
        public int TargetAngle
        {
            get { return _targetAngle; }
            set
            {
                SetValue(ref _targetAngle, value);
                RecalculateArc();
            }
        }

        private double GetRadians(int angle)
        {
            return angle * Math.PI / 180;
        }

        private void RecalculateArc()
        {
            var targetAngle = GetRadians(_targetAngle);
            var fieldOfView = GetRadians(_fieldOfView);
            var halfFieldOfView = fieldOfView / 2;

            var startAngle = targetAngle - halfFieldOfView;
            var endAngle = targetAngle + halfFieldOfView;
            double angleDiff = endAngle - startAngle;
            IsLargeArc = angleDiff >= Math.PI;

            StartPoint = new Point(CenterX + Radius * Math.Cos(startAngle), CenterY + Radius * Math.Sin(startAngle));
            EndPoint = new Point(CenterX + Radius * Math.Cos(endAngle), CenterY + Radius * Math.Sin(endAngle));
        }

        private Point _startPoint;
        public Point StartPoint
        {
            get { return _startPoint; }
            set { SetValue(ref _startPoint, value); }
        }

        private Point _endPoint;
        public Point EndPoint
        {
            get { return _endPoint; }
            set { SetValue(ref _endPoint, value); }
        }

        private bool _isLargeArc;
        public bool IsLargeArc
        {
            get { return _isLargeArc; }
            set { SetValue(ref _isLargeArc, value); }
        }
    }
}

所有的魔法都发生在RecalculateArc每当TargetAngle或被FieldOfView改变时被调用所有的数学运算都必须以弧度表示,所以它做的第一件事就是转换值。使用一些涉及正弦和余弦的相当简单的代数计算新的StartPointEndPointArcSegment(尽管我仍然需要查数学,因为高中毕业后谁还记得这些东西?)。

在 XAML 中,我放置了一些绑定到 的滑块TargetAngle,并FieldOfView允许您控制角度。它还包含Canvas绘制图形的位置,这是在 a 中ViewBox,只是为了使指标填充可用空间。

Canvas包含Path,这是由一个高达PathFigure所述PathFigure在250250(500×500的中心开始Canvas),绘制LineSegment出到弧的起点,这势必会StartPoint一个ArcSegment然后加入,即在端部EndPointIsLargeArc只是用来让绘图系统知道要绘制弧的“一半”。添加另一个LineSegment在中心结束的PathFigure.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在WPF中使用资源字典

来自分类Dev

如何在WPF中使用线程的结果?

来自分类Dev

如何在WPF中使用RxUI交互

来自分类Dev

如何在WPF中使用DateTimePicker绑定

来自分类Dev

如何在SVG Circle元素中使用data- *属性

来自分类Dev

如何在iOS的小视野中打开相机

来自分类Dev

如何使用鼠标在fabricjs中自由绘制Circle?

来自分类Dev

如何在WPF中使用左右键在Tabitem之间导航

来自分类Dev

如何在WPF中使用XAML设置ComboBox标头

来自分类Dev

如何在WPF应用中使用启动事件?

来自分类Dev

如何在WPF应用程序中使用MSHTML

来自分类Dev

如何在WPF中使用Application.Exit事件?

来自分类Dev

如何在WPF中使用Vlc.DotNet?

来自分类Dev

如何在WPF应用程序中使用Ninject

来自分类Dev

如何在菜单项(WPF)中使用“&”

来自分类Dev

如何在WPF中使用图标[Font-awesome]

来自分类Dev

如何在RichTextBox WPF中使用多色

来自分类Dev

如何在WPF中使用线连接椭圆?

来自分类Dev

如何在WPF C#中使用数据绑定?

来自分类Dev

如何在Windows的WPF应用程序中使用ProgressRing

来自分类Dev

如何在WPF中使用动画移动EllipsePath?

来自分类Dev

如何在 WPF 视图模型中使用关系表

来自分类Dev

如何在 WPF/XAML 中使用 Nuget 包中的图标?

来自分类Dev

如何在 WPF 中使用 PropertyChanged 而不是 TextBox TextChanged 事件?

来自分类Dev

如何在 WPF 关闭事件中使用 DerralManager GetDeferral()?

来自分类Dev

如何在 WPF 的循环中使用 DoubleAnimation?

来自分类Dev

如何在Windows Phone中动态绘制扇区(Quarter Circle)?

来自分类Dev

如何在带有死键的Ubuntu 16.04中使用Circle输入A?

来自分类Dev

如何创建Circle ProgressDrawable以在壁画中使用?

Related 相关文章

热门标签

归档