zoukankan      html  css  js  c++  java
  • [WPF] 继承Shape实现弧形、扇形控件

    属性:

    RadianStart:开始弧度,默认值-90,即从最上面开始顺时针画。

    Radian:弧度,默认值0。

    IsSector:是否扇形,默认值False,默认是弧形。

    IsAutoAnimate:是否自动使用动画,默认值False,若为True,则RadianStart和Radian的值变化时,自动使用动画。

    效果展示:

    核心代码:

    private Geometry DrawGeometry()
    {
        // 圆心
        var cx = RenderSize.Width / 2;
        var cy = RenderSize.Height / 2;
    
        // 若控件大小为0,或弧度为0,则不绘制
        if (cx == 0 || cy == 0 || Radian == 0)
            return Geometry.Empty;
    
        var r = Math.Min(cx, cy) - StrokeThickness / 2;  // 半径
        var d = 2 * r; // 直径
    
        // 若弧度恰好为一个整圆,则绘制两个半圆
        if (Radian % 360 == 0)
        {
            // 计算开始、结束弧度坐标点
            var s = CoordMap(cx, cy, r, 0);
            var e = CoordMap(cx, cy, r, 180);
    
            var desc = $"M0 0 M{d} {d} M{s.X} {s.Y} A{r} {r} 0 0 1 {e.X} {e.Y} A{r} {r} 0 0 1 {s.X} {s.Y}";
            var geometry = Geometry.Parse(desc);
            geometry.Freeze();
    
            return geometry;
        }
        else
        {
            // 计算开始、结束弧度坐标点
            var s = CoordMap(cx, cy, r, RadianStart);
            var e = CoordMap(cx, cy, r, RadianStart + Radian);
    
            // 判断是否为大圆
            var lenghty = Radian % 360 > 180 ? 1 : 0;
    
            string desc = null;
    
            // 判断是否扇形
            if (IsSector)
                desc = $"M0 0 M{d} {d} M{cx} {cy} L{s.X} {s.Y} A{r} {r} 0 {lenghty} 1 {e.X} {e.Y} Z";
            else
                desc = $"M0 0 M{d} {d} M{s.X} {s.Y} A{r} {r} 0 {lenghty} 1 {e.X} {e.Y}";
    
            var geometry = Geometry.Parse(desc);
            geometry.Freeze();
    
            return geometry;
        }
    }
    /// <summary>
    /// 极坐标转换
    /// </summary>
    /// <param name="x">圆心x</param>
    /// <param name="y">圆心y</param>
    /// <param name="r">半径</param>
    /// <param name="a">弧度</param>
    /// <returns></returns>
    private Point CoordMap(Double x, Double y, Double r, Double a)
    {
        var ta = (360 - a) * Math.PI / 180;
        var tx = r * Math.Cos(ta); // 角度邻边
        var ty = r * Math.Sin(ta); // 角度的对边
        return new Point(x + tx, y - ty);
    }

    更多详情,请查看PP.WPF控件库。

  • 相关阅读:
    【转】 java中Class对象详解和类名.class, class.forName(), getClass()区别
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    107. Binary Tree Level Order Traversal II
    109. Convert Sorted List to Binary Search Tree
    108. Convert Sorted Array to Binary Search Tree
    110. Balanced Binary Tree
    STL容器迭代器失效问题讨论
    113. Path Sum II
    112. Path Sum
  • 原文地址:https://www.cnblogs.com/pumbaa/p/15009571.html
Copyright © 2011-2022 走看看