WPF 根據角度值繪制圓弧 - ArcSegment


前言

已知一個直徑為 100 的圓,可從12點位置(50,0)順時針繪制指定角度的圓弧。

根據上述的功能描述,我們可得到下列數據:

參數 參數值
圓的直徑 100
繪制的角度 Angle(用戶指定的值,未知變量)
繪制的起點位置 50,0
繪制的方向 Clockwise(順時針)

接下來我們將使用 ArcSegment 對象繪制圓弧,為了便於讀者理解,這里我們對 ArcSegment 中的一些屬性進行一個簡單的說明。

屬性名 屬性說明
IsLargeArc     獲取或設置一個值,該值指示弧是否應大於 180 度。
Point     獲取或設置橢圓弧的終結點。
Size 獲取或設置弧的 X 軸半徑和 Y 軸半徑作為 Size 結構。
SweepDirection     獲取或設置一個值,該值指定是以 Clockwise 方向還是以 Counterclockwise 方向繪制弧。

解決方案

public class ArcSegmentViewModel : ViewModel
{
    private int angle;
    private int diameter = 100;

    /// <summary>
    /// 直徑
    /// </summary>
    public int Diameter
    {
        get => diameter;
        set => this.SetValue(ref diameter, value);
    }

    /// <summary>
    /// 角度
    /// </summary>
    public int Angle
    {
        get => angle;
        set => this.SetValue(ref angle, value);
    }

    public ICommand DrawCommand { get; }

    public ArcSegmentViewModel()
    {
        DrawCommand = new DelegateCommand<Path>(DrawCommandExecuteMethod);
    }

    private void DrawCommandExecuteMethod(Path path)
    {
        Draw1(path);
    }

    private void Draw1(Path path)
    {
        var degree = 180;
        // 0° 和 360° 是重合在一起的,ArcSegment 無法繪制重合的弧度。
        // 所以,最大角度是359。如果,目標值是 360° 則使用 PathFigure 中的屬性 IsClose 閉合圓。
        var maxAngle = 359;
        // 獲取最終角度
        var angle = Math.Min(maxAngle, Angle);
        // 繪制直徑時,需要去掉邊框尺寸,不然繪制的圓會超出正方形。
        var diameter = Diameter - path.StrokeThickness;
        // 根據數學公式計算出當前角度的弧度
        var arc = angle * Math.PI / degree;
        // 獲取正弦值:a/c 
        var sin = Math.Sin(arc);
        // 獲取余弦值:b/c 
        var cos = Math.Cos(arc);
        // 獲取半徑:c
        var radius = diameter / 2;
        // 獲取 a
        var a = radius * sin;
        // 獲取 b
        var b = radius * cos;
        // 獲取終點位置:X
        var x = radius + a;
        // 獲取終點位置:Y
        var y = radius - b;
        // 獲取終點位置
        var endPoint = new Point(x, y);
        var segment = new ArcSegment();
        segment.IsLargeArc = angle > degree;
        segment.SweepDirection = SweepDirection.Clockwise;
        segment.Size = new Size(radius, radius);
        segment.Point = endPoint;
        var figure = new PathFigure();
        // 設置起點位置
        figure.StartPoint = new Point(radius, 0);
        figure.IsClosed = angle >= maxAngle;
        figure.Segments.Add(segment);
        var geometry = new PathGeometry();
        geometry.Figures.Add(figure);
        path.Data = geometry;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM