WPF-24:绘制正多边形_wpf绘制正n边形-程序员宅基地

技术标签: WPF  

一般来说绘制正N边形,使用Blend直接画出来就好。不过可能是博主受WInform影响比较大,比较喜欢使用画出来的图形。如果要绘制正N边形,前面的绘制五角星的公式可以通用的(http://blog.csdn.net/yysyangyangyangshan/article/details/9378871)。
主要是利用圆,根据三角函数和圆的半径计算出圆上的N个点即可。
计算N各点的方法如下:

private PointCollection GetPolygonPoint(Point center, double r,int polygonBound)
        {
            double g = 18;

            double perangle = 360 / polygonBound;

            double pi = Math.PI;

            List<Point> values = new List<Point>();

            for (int i = 0; i < (int) polygonBound; i++)
            {
                Point p2 = new Point(r * Math.Cos((g + 36) * pi / 180), r * Math.Sin((g + 36) * pi / 180));

                values.Add(p2);

                g += perangle;
            }

            PointCollection pcollect = new PointCollection(values);

            return pcollect;
        }

g是起始角度,也是可以修改的。这个方法默认是在原点画出,r表示半径,polygonBound表示边数。
对五角星类做一下简单的修改,
 

public partial class RegularPolygonControl : UserControl
    {
        private double radius = 20;

        private Brush selectBackground = new SolidColorBrush(Color.FromRgb(0xEB, 0x42, 0x00));

        private Brush unselectBackgroud = new SolidColorBrush(Color.FromRgb(0x99, 0x93, 0x93));

        /// <summary>
        /// 半径
        /// </summary>
        public double Radius
        {
            get
            {
                object result = GetValue(RadiusProperty);

                if (result == null)
                {
                    return radius;
                }

                return (double)result;
            }

            set
            {
                SetValue(RadiusProperty, value);

                this.InvalidateVisual();
            }
        }

        public static DependencyProperty RadiusProperty =
           DependencyProperty.Register("Radius", typeof(double), typeof(RegularPolygonControl), new UIPropertyMetadata());


        /// <summary>
        /// 选中颜色
        /// </summary>
        public Brush SelectBackground
        {
            get
            {
                object result = GetValue(SelectBackgroundProperty);

                if (result == null)
                {
                    return selectBackground;
                }

                return (Brush)result;
            }

            set
            {
                SetValue(SelectBackgroundProperty, value);

                //this.InvalidateVisual();
            }
        }

        public static DependencyProperty SelectBackgroundProperty =
           DependencyProperty.Register("SelectBackground", typeof(Brush), typeof(RegularPolygonControl), new UIPropertyMetadata());

        /// <summary>
        /// 未选中颜色
        /// </summary>
        public Brush UnSelectBackground
        {
            get
            {
                object result = GetValue(UnSelectBackgroundProperty);

                if (result == null)
                {
                    return unselectBackgroud;
                }

                return (Brush)result;
            }

            set
            {
                SetValue(UnSelectBackgroundProperty, value);
            }
        }

        public static DependencyProperty UnSelectBackgroundProperty =
           DependencyProperty.Register("UnSelectBackground", typeof(Brush), typeof(RegularPolygonControl), new UIPropertyMetadata());

        protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {
            base.OnRender(dc);

            Point center = new Point();

            PointCollection Points = GetPolygonPoint(center, Radius, 12);

            Canvas ca = new Canvas();

            Polygon plg = new Polygon();

            plg.Points = Points;

            plg.Stroke = Brushes.Transparent;

            plg.StrokeThickness = 2;

            plg.Fill = this.SelectBackground;

            plg.FillRule = FillRule.Nonzero;

            ca.Children.Add(plg);

            ca.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;

            ca.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;

            this.Content = ca;
        }
        

        /// <summary>
        ///根据半径和圆心确定N个点
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        private PointCollection GetPolygonPoint(Point center, double r,int polygonBound)
        {
            double g = 18;

            double perangle = 360 / polygonBound;

            double pi = Math.PI;

            List<Point> values = new List<Point>();

            for (int i = 0; i < (int) polygonBound; i++)
            {
                Point p2 = new Point(r * Math.Cos((g + 36) * pi / 180), r * Math.Sin((g + 36) * pi / 180));

                values.Add(p2);

                g += perangle;
            }

            PointCollection pcollect = new PointCollection(values);

            return pcollect;
        }
    }

效果如下:
   

再做一下简单的变化,可以绘制出一般抽奖用的转盘图形,修改如下,
 

public class TurnTable : UserControl
    {
        private double radius = 20;

        private Brush selectBackground = new SolidColorBrush(Color.FromRgb(0xEB, 0x42, 0x00));

        private Brush unselectBackgroud = new SolidColorBrush(Color.FromRgb(0x99, 0x93, 0x93));

        /// <summary>
        /// 半径
        /// </summary>
        public double Radius
        {
            get
            {
                object result = GetValue(RadiusProperty);

                if (result == null)
                {
                    return radius;
                }

                return (double)result;
            }

            set
            {
                SetValue(RadiusProperty, value);

                this.InvalidateVisual();
            }
        }

        public static DependencyProperty RadiusProperty =
           DependencyProperty.Register("Radius", typeof(double), typeof(TurnTable), new UIPropertyMetadata());


        /// <summary>
        /// 选中颜色
        /// </summary>
        public Brush SelectBackground
        {
            get
            {
                object result = GetValue(SelectBackgroundProperty);

                if (result == null)
                {
                    return selectBackground;
                }

                return (Brush)result;
            }

            set
            {
                SetValue(SelectBackgroundProperty, value);

                //this.InvalidateVisual();
            }
        }

        public static DependencyProperty SelectBackgroundProperty =
           DependencyProperty.Register("SelectBackground", typeof(Brush), typeof(TurnTable), new UIPropertyMetadata());


        protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {
            base.OnRender(dc);

            Point center = new Point();

            PointCollection Points = GetPolygonPoint(center, Radius, 12);

            Canvas ca = new Canvas();

            Polygon plg = new Polygon();

            plg.Points = Points;

            plg.Stroke = Brushes.Black;

            plg.StrokeThickness = 2;

            plg.Fill = this.SelectBackground;

            plg.FillRule = FillRule.Nonzero;

            ca.Children.Add(plg);


            //外接圆
            Brush b = new SolidColorBrush(Colors.Yellow);

            Pen p = new Pen(b, 2);

            var path = new Path();

            double circleRadius = Radius + 10;

            EllipseGeometry eg = new EllipseGeometry(center, circleRadius, circleRadius);

            path.Stroke = Brushes.Black;

            path.StrokeThickness = 1;

            path.Data = eg;

            ca.Children.Add(path);


            ca.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;

            ca.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;

            this.Content = ca;
        }


        /// <summary>
        ///根据半径和圆心确定N个点
        /// </summary>
        /// <param name="center"></param>
        /// <returns></returns>
        private PointCollection GetPolygonPoint(Point center, double r, int polygonBound)
        {
            double g = 18;

            double perangle = 360 / polygonBound;

            double pi = Math.PI;

            List<Point> values = new List<Point>();

            for (int i = 0; i < (int)polygonBound; i++)
            {
                Point p2 = new Point(r * Math.Cos((g + 36) * pi / 180), r * Math.Sin((g + 36) * pi / 180));

                values.Add(p2);

                values.Add(center);

                g += perangle;
            }

            PointCollection pcollect = new PointCollection(values);

            return pcollect;
        }
    }

这样 两个控件一起看一下效果,

<Window x:Class="TestSomeGraphics.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Width="1200" Height="900" xmlns:my="clr-namespace:TestSomeGraphics">
    
    <Grid>
        <my:RegularPolygonControl HorizontalAlignment="Left" x:Name="regularControl1"  Radius="200" SelectBackground="Gray" 
                                  Margin="235,358,0,-358" />
        <my:TurnTable HorizontalAlignment="Left" Radius="100" Margin="639,358,0,0" x:Name="turnTableControl1" VerticalAlignment="Top" />
    </Grid>

</Window>

如图,

 代码下载:http://download.csdn.net/detail/yysyangyangyangshan/6326307

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yysyangyangyangshan/article/details/12068077

智能推荐

git工具的使用方法以及与snv的区别_snv git-程序员宅基地

文章浏览阅读371次。给大家推荐一个廖雪峰老师讲解git的网站:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000一、SVN与git的区别 SVN是“集成式”管理方式,所有的“版本控制器”都在中央服务器上,每个开发人员的的计算机都要连接到中央服务器上才能进行合作开发。开发人员一般只能在公司才能进行开发(因..._snv git

Centos7安装部署RabbitMQ及配置-程序员宅基地

文章浏览阅读4.4k次,点赞3次,收藏4次。1 简介RabbitMQ是一个开源的免费的消息队列系统,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅队列中的消息。它是用Erlang编写的,并实现了高级消息队列协议(AMQP)。2 安装部署2.1 安装EPEL存储库和Erlang安装RabbitMQ是用Erlang语言编写的,在本教程中我们将安装最新版本的Erlang到服务器中。 Erlang在默认的YUM存储库中不可用,因此...

ubuntu下搭建ad-hoc网络实现多台设备进行网络通信(通过图形界面+超级详细教程)_测试ad-hoc无线网络的连通性-程序员宅基地

文章浏览阅读3.2k次,点赞9次,收藏20次。最近实验室做的一些工作需要使用lattepanda(类似增强的树莓派)并且使用其无线网卡的ad-hoc模式,并且实现多台lattepanda之间实现网络通信。_测试ad-hoc无线网络的连通性

ubuntu 禁用透明大页_linux 关闭透明大页-程序员宅基地

文章浏览阅读261次。oracle 建议关闭透明大页[root@ht01 ~]# cat /etc/grub.conf# grub.conf generated by anaconda## Note that you do not have to rerun grub after making changes to this file# NOTICE: You have a /boot partition. Thi..._ubuntu grub 关闭透明大页

deepin v20 beta 安装 Vmware 15步骤_deepin安装vmware15-程序员宅基地

文章浏览阅读1.3k次。deepin v20默认是装不了vmware15的,因为vm15 依赖 gcc6 而deepin v20 默认是gcc8,版本太高了,所以要先安装gcc6,但是默认的源里没有gcc6及以下版本,所以要从换源开始。第一步 换阿里云的源1:快捷键“Ctrl + Alt + T”打开命令输入框,输入sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak备份当前配置回车后 需要你输入你的开机密码再输入sudo dedit /..._deepin安装vmware15

Html+Css 3D旋转立方体_cao96-程序员宅基地

文章浏览阅读3.7k次,点赞2次,收藏10次。在上一篇的Html+Css+Js 3D旋转爱心 中间可插图片的代码基础上稍做修改获得两个大小不一3D旋转立方体,留作记忆,代码如下:<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-Type" conten..._cao96

随便推点

风格迁移(CycleGAN)_cyclegan 指标-程序员宅基地

文章浏览阅读3.9k次。文章目录概述CycleGANCycleGAN有两个Generator网络CycleGAN有两个Discriminator网络CycleGAN的网络结构应用参考概述Cycle-Consistent Adversarial Networks(CycleGAN)是一个新颖的方法,它能将图像从源域映射到目标域b。CycleGANs的一个很酷的功能是它不需要训练数据配对就能产生惊人的风格传递的结果。在许多风格迁移的应用中,成对数据是训练所必需的。配对CycleGAN不需要配对数据输入到模型中无需_cyclegan 指标

Unity中,使“鼠标点击”穿透UI,触发物体事件_unity ui穿透-程序员宅基地

文章浏览阅读1.2w次,点赞9次,收藏78次。Unity中,使“鼠标点击”穿透UI,触发物体事件_unity ui穿透

漫步线性代数二十一——行列式引言_将visa换成avis需要多少次对换,是奇数吗-程序员宅基地

文章浏览阅读1k次。在一百年前,行列式不是线性代数的中心,但是数学的方向一直在变换!毕竟,仅仅一个数就能告诉我们许多矩阵的信息。对行列式的一种理解是:它对A−1,A−1bA^{-1},A^{-1}b的每一项给出了明确的方式,这个公式不会随着我们的计算方法而改变。事实上,我们可以将行列式看成n×nn\times n矩阵最有效的替代公式,这个公式说明了A−1A^{-1}如何依赖AA的n2n^2个元素,以及这些元素变化时这个_将visa换成avis需要多少次对换,是奇数吗

Linux系统的ftp服务(ftp搭建及相关用法)_liunx系统ftp服务器架构设计-程序员宅基地

文章浏览阅读647次。部署FTP服务FTP(文本传输协议)是INTERNET上仍常用的最老的网络协议之一,它为系统提供了通过网络与远程服务器进行传输的简单方法。FTP服务器包的名称为vsftpd,它代表very secure file transferprotocol damon 服务器名称也叫做vsftpd.默认配置文件让匿名用户(anoymous用户)只能呢个下在位于chroot 目录中的内容。/var/f..._liunx系统ftp服务器架构设计

微信小程序--API--wx.request_wx.request的最大超时时长是多少? 想设置三分钟-程序员宅基地

文章浏览阅读1k次。API以wx.开头,如未特殊约定,一般都以接受一个object作为参数。 其中wx.on开头的API是监听某个事件发生的API接口,接收一个callback函数。当事件出发时,会调用callback函数。API主要用于逻辑层的开发,实现原生应用具有的一些功能。列如利用网络API获取丰富的内容、通过媒体API实现多样化信息交流,等待。wx.request用于发一个HTTPS请求。一个微信小..._wx.request的最大超时时长是多少? 想设置三分钟

完美解决 node.js 模块化后报错 ReferenceError require is not defined_node_modules/crypto-js/crypto-js.js' is not define-程序员宅基地

文章浏览阅读1.3k次。原理分析:这是由于从node.js 14版及以上版本中,require作为COMMONJS的一个命令已不再直接支持使用,所以我们需要导入createRequire命令才可以解决方案在你要require的代码前引入如下代码即可:import { createRequire } from 'module';const require = createRequire(import.meta.url);..._node_modules/crypto-js/crypto-js.js' is not defined, require args is '../no

推荐文章

热门文章

相关标签