Browse Source

Update Arc.cs

pull/6133/head
Jumar Macato 5 years ago
committed by GitHub
parent
commit
f5ded26321
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      src/Avalonia.Controls/Shapes/Arc.cs

47
src/Avalonia.Controls/Shapes/Arc.cs

@ -28,33 +28,34 @@ namespace Avalonia.Controls.Shapes
/// </summary> /// </summary>
public double StartAngle public double StartAngle
{ {
get { return GetValue(StartAngleProperty); } get => GetValue(StartAngleProperty);
set { SetValue(StartAngleProperty, value); } set => SetValue(StartAngleProperty, value);
} }
/// <summary> /// <summary>
/// Gets or sets the angle, in degrees, added to the <see cref="StartAngle"/> defining where the arc ends. A positive value is clockwise, negative is counter-clockwise. /// Gets or sets the angle, in degrees, added to the <see cref="StartAngle"/> defining where the arc ends.
/// A positive value is clockwise, negative is counter-clockwise.
/// </summary> /// </summary>
public double SweepAngle public double SweepAngle
{ {
get { return GetValue(SweepAngleProperty); } get => GetValue(SweepAngleProperty);
set { SetValue(SweepAngleProperty, value); } set => SetValue(SweepAngleProperty, value);
} }
protected override Geometry CreateDefiningGeometry() protected override Geometry CreateDefiningGeometry()
{ {
double angle1 = DegreesToRad(StartAngle); var angle1 = DegreesToRad(StartAngle);
double angle2 = angle1 + DegreesToRad(SweepAngle); var angle2 = angle1 + DegreesToRad(SweepAngle);
double startAngle = Math.Min(angle1, angle2); var startAngle = Math.Min(angle1, angle2);
double sweepAngle = Math.Max(angle1, angle2); var sweepAngle = Math.Max(angle1, angle2);
double normStart = RadToNormRad(startAngle); var normStart = RadToNormRad(startAngle);
double normEnd = RadToNormRad(sweepAngle); var normEnd = RadToNormRad(sweepAngle);
var rect = new Rect(Bounds.Size); var rect = new Rect(Bounds.Size);
if ((normStart == normEnd) && (startAngle != sweepAngle)) // complete ring if ((normStart == normEnd) && (startAngle != sweepAngle)) // Complete ring.
{ {
return new EllipseGeometry(rect.Deflate(StrokeThickness / 2)); return new EllipseGeometry(rect.Deflate(StrokeThickness / 2));
} }
@ -62,28 +63,30 @@ namespace Avalonia.Controls.Shapes
{ {
return new StreamGeometry(); return new StreamGeometry();
} }
else // partial arc else // Partial arc.
{ {
var deflatedRect = rect.Deflate(StrokeThickness / 2); var deflatedRect = rect.Deflate(StrokeThickness / 2);
double centerX = rect.Center.X; var centerX = rect.Center.X;
double centerY = rect.Center.Y; var centerY = rect.Center.Y;
double radiusX = deflatedRect.Width / 2; var radiusX = deflatedRect.Width / 2;
double radiusY = deflatedRect.Height / 2; var radiusY = deflatedRect.Height / 2;
double angleGap = RadToNormRad(sweepAngle - startAngle); var angleGap = RadToNormRad(sweepAngle - startAngle);
Point startPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, startAngle); var startPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, startAngle);
Point endPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, sweepAngle); var endPoint = GetRingPoint(radiusX, radiusY, centerX, centerY, sweepAngle);
StreamGeometry arcGeometry = new StreamGeometry(); var arcGeometry = new StreamGeometry();
using (var ctx = arcGeometry.Open()) using (var ctx = arcGeometry.Open())
{ {
ctx.BeginFigure(startPoint, false); ctx.BeginFigure(startPoint, false);
ctx.ArcTo(endPoint, new Size(radiusX, radiusY), angleGap, angleGap >= Math.PI, SweepDirection.Clockwise); ctx.ArcTo(endPoint, new Size(radiusX, radiusY), angleGap, angleGap >= Math.PI, SweepDirection.Clockwise);
ctx.EndFigure(false); ctx.EndFigure(false);
} }
return arcGeometry; return arcGeometry;
} }
} }
@ -91,7 +94,7 @@ namespace Avalonia.Controls.Shapes
static double DegreesToRad(double inAngle) => static double DegreesToRad(double inAngle) =>
inAngle * Math.PI / 180; inAngle * Math.PI / 180;
static double RadToNormRad(double inAngle) => (0 + (inAngle % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2); static double RadToNormRad(double inAngle) => (inAngle % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2);
static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) => static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) =>
new Point((radiusX * Math.Cos(angle)) + centerX, (radiusY * Math.Sin(angle)) + centerY); new Point((radiusX * Math.Cos(angle)) + centerX, (radiusY * Math.Sin(angle)) + centerY);

Loading…
Cancel
Save