前言
已知一個直徑為 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;
}
}