• [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控件库。

  • 相关阅读:
    【转载】ARM与单片机的区别
    关于头文件定义的一点思考
    关于*** WARNING L15: MULTIPLE CALL TO SEGMENT
    【转】单片机中volatile定义的作用详解
    关于单片机位数的思考(8位、16位、32位)
    memcpy函数
    ubuntu下打开windows里的txt文件乱码解决
    linux source filename
    linux环境设置export
    pdf转word工具
  • 原文地址:https://www.cnblogs.com/pumbaa/p/15009571.html
Copyright © 2020-2023  润新知