This repository has been archived on 2022-08-05. You can view files and clone it, but cannot push or open issues or pull requests.
Lemonade/Lemonade/Fakku.cs

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;
}
}
}
}
}
}