diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
index 1063f504b6..09fd8d7abf 100644
--- a/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Graphics.MicroGraphics/Driver/MicroGraphics.cs
@@ -1,5 +1,6 @@
using Meadow.Foundation.Graphics.Buffers;
using Meadow.Peripherals.Displays;
+using Meadow.Units;
using System;
using System.Threading.Tasks;
@@ -484,6 +485,90 @@ public void DrawVerticalLine(int x, int y, int length, Color color)
Fill(x, y - yOffset, width, length, color);
}
+ ///
+ /// Draw a circular arc between two angles
+ ///
+ ///
+ /// Note that y axis is inversed so the arc will be flipped from the standard cartesian plain
+ ///
+ /// Abscissa of the centre point of the circle
+ /// Ordinate of the centre point of the circle
+ /// Radius of the circle
+ /// The arc starting angle
+ /// The arc ending angle
+ /// The color of the circle
+ /// If true, the center of the arc is between the assigned pixel and the next pixel, false it's directly on the center pixel
+
+ public void DrawArc(int centerX, int centerY, int radius, Angle startAngle, Angle endAngle, Color color, bool centerBetweenPixels)
+ {
+ var d = 3 - 2 * radius;
+ var x = 0;
+ var y = radius;
+
+ int offset = centerBetweenPixels ? 1 : 0;
+
+ var start = new Angle(startAngle.Degrees + 0);
+ var end = new Angle(endAngle.Degrees + 0);
+
+ int strokeOffset = Stroke / 2;
+
+ if (end < start)
+ {
+ end += new Angle(360);
+ }
+
+ bool IsCoordinateOnArc(int x, int y, int octect)
+ {
+ var angle = Math.Atan2(-y, x);
+ if (angle < 0) { angle += 2 * Math.PI; }
+
+ if (angle >= start.Radians && angle <= end.Radians)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ void DrawArcPoint(int x, int y, Color color)
+ {
+ if (Stroke == 1)
+ {
+ DrawPixel(x, y, color);
+ }
+ else
+ {
+ DrawCircleFilled(x, y, Stroke / 2, true, color);
+ }
+ }
+
+ while (x <= y)
+ {
+ if (IsCoordinateOnArc(y, -x, 1)) DrawArcPoint(centerX + y - offset, centerY - x, color); //1
+ if (IsCoordinateOnArc(x, -y, 2)) DrawArcPoint(centerX + x - offset, centerY - y, color); //2
+
+ if (IsCoordinateOnArc(-x, -y, 3)) DrawArcPoint(centerX - x, centerY - y, color); //3
+ if (IsCoordinateOnArc(-y, -x, 4)) DrawArcPoint(centerX - y, centerY - x, color); //4
+
+ if (IsCoordinateOnArc(-y, x, 5)) DrawArcPoint(centerX - y, centerY + x - offset, color); //5
+ if (IsCoordinateOnArc(-x, y, 6)) DrawArcPoint(centerX - x, centerY + y - offset, color); //6
+
+ if (IsCoordinateOnArc(x, y, 7)) DrawArcPoint(centerX + x - offset, centerY + y - offset, color); //7
+ if (IsCoordinateOnArc(y, x, 8)) DrawArcPoint(centerX + y - offset, centerY + x - offset, color); //8
+
+ if (d < 0)
+ {
+ d += (2 * x) + 1;
+ }
+ else
+ {
+ d += (2 * (x - y)) + 1;
+ y--;
+ }
+ x++;
+ }
+
+ }
+
///
/// Draw a triangle
///
@@ -857,7 +942,7 @@ private void DrawCircleQuadrantOutline(int centerX, int centerY, int radius, int
private void DrawCircleOutline(int centerX, int centerY, int radius, bool centerBetweenPixels, Color color)
{
//I prefer the look of the original Bresenham’s decision param calculation
- var d = 3 - 2 * radius; // (5 - (radius * 4)) / 4;
+ var d = 3 - 2 * radius;
var x = 0;
var y = radius;
@@ -900,10 +985,10 @@ private void DrawCircleFilled(int centerX, int centerY, int radius, bool centerB
while (x <= y)
{
- DrawHorizontalLine(centerX - x, centerY + y - offset, 2 * x - offset, color);
- DrawHorizontalLine(centerX - x, centerY - y, 2 * x - offset, color);
- DrawHorizontalLine(centerX - y, centerY + x - offset, 2 * y - offset, color);
- DrawHorizontalLine(centerX - y, centerY - x, 2 * y - offset, color);
+ DrawHorizontalLine(centerX - x, centerY + y - offset, 2 * x - offset + 1, color);
+ DrawHorizontalLine(centerX - x, centerY - y, 2 * x - offset + 1, color);
+ DrawHorizontalLine(centerX - y, centerY + x - offset, 2 * y - offset + 1, color);
+ DrawHorizontalLine(centerX - y, centerY - x, 2 * y - offset + 1, color);
if (d < 0)
{
@@ -916,6 +1001,16 @@ private void DrawCircleFilled(int centerX, int centerY, int radius, bool centerB
}
x++;
}
+
+ if (Stroke > 1)
+ {
+ offset = Stroke >> 1;
+
+ for (int i = 0; i < Stroke; i++)
+ {
+ DrawCircleOutline(centerX, centerY, radius - offset + i, centerBetweenPixels, color);
+ }
+ }
}
///