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

  • 相关阅读:
    skywalking源码改造
    skywalking包覆盖
    skywalking-拦截器实现(2)
    skywalking-拦截器实现(1)
    skywalking-过滤某些不需要被监控的接口
    扩展Spring-data-jpa导致注解@NamedEntityGraphs失效
    Skywalking日志收集功能使用:
    LRU缓存机制(基于LinkedHashMap)
    2020年总结
    Hbase简介
  • 原文地址:https://www.cnblogs.com/pumbaa/p/15009571.html
Copyright © 2011-2022 走看看