WPF-24:绘制正多边形

一般来说绘制正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

 

posted on 2013-09-26 21:34  you Richer  阅读(810)  评论(0编辑  收藏  举报