using System;
using System.Collections.Generic;
using System.Windows;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SketchAssistantWPF
{
///
/// A class that contains all algorithms related to geometry.
///
public static class GeometryCalculator
{
///
/// A simple algorithm that returns a filled circle with a radius and a center point.
///
/// The center point of the alorithm
/// The radius of the circle, if its less or equal to 1
/// only the center point is returned.
/// All the points in or on the circle.
public static HashSet FilledCircleAlgorithm(Point center, int radius)
{
HashSet returnSet = new HashSet { center };
//Fill the circle
for (int x = 0; x < radius; x++)
{
for (int y = 0; y < radius; y++)
{
//Check if point is on or in the circle
if ((x * x + y * y - radius * radius) <= 0)
{
returnSet.Add(new Point(center.X + x, center.Y + y));
returnSet.Add(new Point(center.X - x, center.Y + y));
returnSet.Add(new Point(center.X + x, center.Y - y));
returnSet.Add(new Point(center.X - x, center.Y - y));
}
}
}
return returnSet;
}
///
/// An implementation of the Bresenham Line Algorithm,
/// which calculates all points between two points in a straight line.
/// Implemented using the pseudocode on Wikipedia.
///
/// The start point
/// The end point
/// All points between p0 and p1 (including p0 and p1)
public static List BresenhamLineAlgorithm(Point p0, Point p1)
{
int p1x = (int)p1.X;
int p1y = (int)p1.Y;
int p0x = (int)p0.X;
int p0y = (int)p0.Y;
int deltaX = p1x - p0x;
int deltaY = p1y - p0y;
List returnList;
if (Math.Abs(deltaY) < Math.Abs(deltaX))
{
if (p0.X > p1.X)
{
returnList = GetLineLow(p1x, p1y, p0x, p0y);
returnList.Reverse();
}
else
{
returnList = GetLineLow(p0x, p0y, p1x, p1y);
}
}
else
{
if (p0.Y > p1.Y)
{
returnList = GetLineHigh(p1x, p1y, p0x, p0y);
returnList.Reverse();
}
else
{
returnList = GetLineHigh(p0x, p0y, p1x, p1y);
}
}
return returnList;
}
///
/// Helping function of the Bresenham Line algorithm,
/// under the assumption that abs(deltaY) is smaller than abs(deltX)
/// and x0 is smaller than x1
///
/// x value of point 0
/// y value of point 0
/// x value of point 1
/// y value of point 1
/// All points on the line between the two points
private static List GetLineLow(int x0, int y0, int x1, int y1)
{
List returnList = new List();
int dx = x1 - x0;
int dy = y1 - y0;
int yi = 1;
if (dy < 0)
{
yi = -1;
dy = -dy;
}
int D = 2 * dy - dx;
int y = y0;
for (int x = x0; x <= x1; x++)
{
returnList.Add(new Point(x, y));
if (D > 0)
{
y = y + yi;
D = D - 2 * dx;
}
D = D + 2 * dy;
}
return returnList;
}
///
/// Helping function of the Bresenham Line algorithm,
/// under the assumption that abs(deltaY) is larger or equal than abs(deltX)
/// and y0 is smaller than y1
///
/// x value of point 0
/// y value of point 0
/// x value of point 1
/// y value of point 1
/// All points on the line between the two points
private static List GetLineHigh(int x0, int y0, int x1, int y1)
{
List returnList = new List();
int dx = x1 - x0;
int dy = y1 - y0;
int xi = 1;
if (dx < 0)
{
xi = -1;
dx = -dx;
}
int D = 2 * dx - dy;
int x = x0;
for (int y = y0; y <= y1; y++)
{
returnList.Add(new Point(x, y));
if (D > 0)
{
x = x + xi;
D = D - 2 * dy;
}
D = D + 2 * dx;
}
return returnList;
}
}
}