WPF根据起始角度或旋转角度绘制弧线

编程入门 行业动态 更新时间:2024-10-17 05:30:38

WPF根据起始<a href=https://www.elefans.com/category/jswz/34/1771447.html style=角度或旋转角度绘制弧线"/>

WPF根据起始角度或旋转角度绘制弧线

 实现指定圆心与起止角度;或指定圆心、起点与旋转角度,绘制弧线。

参考文章:How to draw arc with radius and start and stop angle-stackoverflow 

主要在原回答基础上增加了相对起点的旋转参数,更改了部分显示逻辑。

xaml插入方式参考原文

修改后的控件代码如下:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;namespace Controls
{public class Arc : Shape{public Point Center{get => (Point)GetValue(CenterProperty);set => SetValue(CenterProperty, value);}// Using a DependencyProperty as the backing store for Center.  This enables animation, styling, binding, etc...public static readonly DependencyProperty CenterProperty =DependencyProperty.Register(nameof(Center), typeof(Point), typeof(Arc),new FrameworkPropertyMetadata(new Point(), FrameworkPropertyMetadataOptions.AffectsRender));public double StartAngle{get => (double)GetValue(StartAngleProperty);set => SetValue(StartAngleProperty, value);}// Using a DependencyProperty as the backing store for StartAngle.  This enables animation, styling, binding, etc...public static readonly DependencyProperty StartAngleProperty =DependencyProperty.Register(nameof(StartAngle), typeof(double), typeof(Arc),new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));public double EndAngle{get => (double)GetValue(EndAngleProperty);set => SetValue(EndAngleProperty, value);}// Using a DependencyProperty as the backing store for EndAngle.  This enables animation, styling, binding, etc...public static readonly DependencyProperty EndAngleProperty =DependencyProperty.Register(nameof(EndAngle), typeof(double), typeof(Arc),new FrameworkPropertyMetadata(90.0, FrameworkPropertyMetadataOptions.AffectsRender));public double RotateAngle{get => (double)GetValue(RotateAngleProperty);set => SetValue(RotateAngleProperty, value);}// Using a DependencyProperty as the backing store for EndAngle.  This enables animation, styling, binding, etc...public static readonly DependencyProperty RotateAngleProperty =DependencyProperty.Register(nameof(RotateAngle), typeof(double), typeof(Arc),new FrameworkPropertyMetadata(90.0, FrameworkPropertyMetadataOptions.AffectsRender));public double Radius{get => (double)GetValue(RadiusProperty);set => SetValue(RadiusProperty, value);}// Using a DependencyProperty as the backing store for Radius.  This enables animation, styling, binding, etc...public static readonly DependencyProperty RadiusProperty =DependencyProperty.Register(nameof(Radius), typeof(double), typeof(Arc),new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender));public bool Clockwise{get => (bool)GetValue(ClockwiseProperty);set => SetValue(ClockwiseProperty, value);}// Using a DependencyProperty as the backing store for SmallAngle.  This enables animation, styling, binding, etc...public static readonly DependencyProperty ClockwiseProperty =DependencyProperty.Register(nameof(Clockwise), typeof(bool), typeof(Arc),new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));static Arc() => DefaultStyleKeyProperty.OverrideMetadata(typeof(Arc), new FrameworkPropertyMetadata(typeof(Arc)));protected override Geometry DefiningGeometry{get{if (RotateAngle == 90.0 && EndAngle == 90.0){//若均为初始值,选择rotate优先EndAngle = Clockwise? StartAngle + (double)RotateAngle : StartAngle - (double)RotateAngle;}//若有旋转角度,则用旋转角度计算endif (RotateAngle != 90.0){EndAngle = Clockwise ? StartAngle + (double)RotateAngle : StartAngle - (double)RotateAngle;}if(Math.Abs(StartAngle-EndAngle)>=360){//差值大于360度,画圆return new EllipseGeometry(Center,Radius,Radius);}//起止都约束到360度内long temp0 = Convert.ToInt64(StartAngle);long temp1 = Convert.ToInt64(EndAngle);StartAngle = StartAngle - temp0 + temp0 % 360;EndAngle = EndAngle - temp1 + temp1 % 360;//不需特意实现//if (StartAngle == EndAngle)//{//起止点相同,画点。//}//起止都修正为正值double a0 = StartAngle < 0 ? StartAngle + 360 : StartAngle;double a1 = EndAngle < 0 ? EndAngle + 360 : EndAngle;//起止都转为弧度a0 = a0 / 180.0 * Math.PI;a1 = a1 / 180.0 * Math.PI;if (a1 < a0){a1 += Math.PI * 2;//不影响sin与cos值}//差大于PI时,顺时针为优弧;差小于PI时,顺时针为劣弧。//默认为顺时针优弧。SweepDirection d;bool large;//是否是优弧//判断是优弧还是劣弧if (Clockwise){d = SweepDirection.Clockwise;large = (Math.Abs(a1 - a0) > Math.PI);}else{d = SweepDirection.Counterclockwise;large = (Math.Abs(a1 - a0) < Math.PI);}Point p0 = Center + new Vector(Math.Cos(a0), Math.Sin(a0)) * Radius;Point p1 = Center + new Vector(Math.Cos(a1), Math.Sin(a1)) * Radius;List<PathSegment> segments = new List<PathSegment>{//使用起止点绘图——设置终点与半径new ArcSegment(p1, new Size(Radius, Radius), 0.0, large, d, true)};List<PathFigure> figures = new List<PathFigure>{//使用起止点绘图——设置起点new PathFigure(p0, segments, true){IsClosed = false}};return new PathGeometry(figures, FillRule.EvenOdd, null);}}}
}

 

更多推荐

WPF根据起始角度或旋转角度绘制弧线

本文发布于:2024-02-10 21:43:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1677448.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:角度   弧线   WPF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!