88 lines
3.8 KiB
C#
88 lines
3.8 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using CC_Functions.Commandline.TUI;
|
|
|
|
namespace Lemonade
|
|
{
|
|
//Mostly kang from Stackoverflow
|
|
public static class EllipseDrawer
|
|
{
|
|
private static PointF GetEllipsePointFromX(float x, float a, float b) =>
|
|
new PointF(x, b * -(float) Math.Sqrt(1 - x * x / a / a));
|
|
|
|
public static void DrawEllipse(this Pixel[,] target, Rectangle area, Pixel basePixel)
|
|
{
|
|
int p0 = target.GetLength(0);
|
|
int p1 = target.GetLength(1);
|
|
bool[,] tmp = new bool[p0, p1];
|
|
DrawEllipse(tmp, new Rectangle(area.Y, area.X, area.Height, area.Width));
|
|
for (int i = 0; i < p0; i++)
|
|
for (int j = 0; j < p1; j++)
|
|
if (tmp[i, j])
|
|
target[i, j] = basePixel;
|
|
}
|
|
|
|
private static void DrawEllipse(bool[,] pixels, Rectangle area)
|
|
{
|
|
int matrixWidth = pixels.GetLength(0);
|
|
int matrixHeight = pixels.GetLength(1);
|
|
int offsetY = area.Top;
|
|
int offsetX = area.Left;
|
|
float ellipseWidth = area.Width;
|
|
float ellipseHeight = area.Height;
|
|
float radiusX = ellipseWidth / 2;
|
|
float radiusY = ellipseHeight / 2;
|
|
int prevY = 0;
|
|
bool firstRun = true;
|
|
for (int x = 0; x <= radiusX; ++x)
|
|
{
|
|
int xPos = x + offsetX;
|
|
int rxPos = (int) ellipseWidth - x - 1 + offsetX;
|
|
if (xPos < 0 || rxPos < xPos || xPos >= matrixWidth) continue;
|
|
PointF pointOnEllipseBoundCorrespondingToXMatrixPosition =
|
|
GetEllipsePointFromX(x - radiusX, radiusX, radiusY);
|
|
int y = (int) Math.Floor(pointOnEllipseBoundCorrespondingToXMatrixPosition.Y + (int) radiusY);
|
|
int yPos = y + offsetY;
|
|
int ryPos = (int) ellipseHeight - y - 1 + offsetY;
|
|
if (yPos >= 0)
|
|
{
|
|
if (xPos < matrixWidth && yPos < matrixHeight) pixels[xPos, yPos] = true;
|
|
if (xPos < matrixWidth && ryPos > -1 && ryPos < matrixHeight) pixels[xPos, ryPos] = true;
|
|
if (rxPos < matrixWidth)
|
|
{
|
|
if (yPos < matrixHeight) pixels[rxPos, yPos] = true;
|
|
if (ryPos > -1 && ryPos < matrixHeight) pixels[rxPos, ryPos] = true;
|
|
}
|
|
}
|
|
for (int j = prevY - 1; !firstRun && j > y - 1 && y > 0; --j)
|
|
{
|
|
int jPos = j + offsetY;
|
|
int rjPos = (int) ellipseHeight - j - 1 + offsetY;
|
|
if (jPos == rjPos - 1) continue;
|
|
if (jPos > -1 && jPos < matrixHeight) pixels[xPos, jPos] = true;
|
|
if (rjPos > -1 && rjPos < matrixHeight) pixels[xPos, rjPos] = true;
|
|
if (rxPos < matrixWidth)
|
|
{
|
|
if (jPos > -1 && jPos < matrixHeight) pixels[rxPos, jPos] = true;
|
|
if (rjPos > -1 && rjPos < matrixHeight) pixels[rxPos, rjPos] = true;
|
|
}
|
|
}
|
|
firstRun = false;
|
|
prevY = y;
|
|
float countTarget = radiusY - y;
|
|
for (int count = 0; count < countTarget; ++count)
|
|
{
|
|
++yPos;
|
|
--ryPos;
|
|
if (yPos > -1 && yPos < matrixHeight) pixels[xPos, yPos] = true;
|
|
if (ryPos > -1 && ryPos < matrixHeight) pixels[xPos, ryPos] = true;
|
|
if (rxPos < matrixWidth)
|
|
{
|
|
if (yPos > -1 && yPos < matrixHeight) pixels[rxPos, yPos] = true;
|
|
if (ryPos > -1 && ryPos < matrixHeight) pixels[rxPos, ryPos] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |