private Point[] SquaresBetweenPoints(Point from, Point to)
{
var points = new HashSet<Point>();
if (from == to)
{
return new Point[] {from};
}
// if the lines are completely vertical
if (from.X == to.X)
{
int step = (to.Y - from.Y)/Math.Abs(to.Y - from.Y);
for (int y = from.Y; y != to.Y; y += step)
{
points.Add(new Point(from.X, y));
}
}
// if the lines are completely horizontal
else if (from.Y == to.Y)
{
int step = (to.X - from.X)/Math.Abs(to.X - from.X);
for (int x = from.X; x != to.X; x += step)
{
points.Add(new Point(x, from.Y));
}
}
// the line is not straight
else
{
// if we are going left instead of right, switch the from and to
if (from.X > to.X)
{
var temp = from;
from = to;
to = temp;
}
// calculate the angle of descent/decline
double a = (double) (to.Y - from.Y)/(to.X - from.X);
// step by 0.5 from the from x-coordinate to the to x-coordinate
for (double xn = from.X + .5; xn < to.X; xn++)
{
// calculate the y-value
double yn = (xn - from.X)*a + from.Y;
if (Math.Abs(yn - Math.Truncate(yn) - .5) < .0000001)
{
if (a < 0)
{
points.Add(new Point((int) Math.Truncate(xn), (int) Math.Ceiling(yn)));
points.Add(new Point((int) Math.Ceiling(xn), (int) Math.Truncate(yn)));
}
else
{
points.Add(new Point((int) Math.Truncate(xn), (int) Math.Truncate(yn)));
points.Add(new Point((int) Math.Ceiling(xn), (int) Math.Ceiling(yn)));
}
}
else
{
points.Add(new Point((int) Math.Truncate(xn), (int) Math.Round(yn)));
points.Add(new Point((int) Math.Truncate(xn) + 1, (int) Math.Round(yn)));
}
}
if (from.Y > to.Y)
{
var temp = from;
from = to;
to = temp;
}
// step by 0.5 from the from y-coordinate to the to y-coordinate
for (double yn = from.Y + .5; yn < to.Y; yn++)
{
// calculates the x value
double xn = (yn - from.Y)/a + from.X;
if (Math.Abs(xn - Math.Truncate(xn) - .5) < .000001)
{
if (a < 0)
{
points.Add(new Point((int) Math.Truncate(xn), (int) Math.Ceiling(yn)));
points.Add(new Point((int) Math.Ceiling(xn), (int) Math.Truncate(yn)));
}
else
{
points.Add(new Point((int) Math.Truncate(xn), (int) Math.Truncate(yn)));
points.Add(new Point((int) Math.Ceiling(xn), (int) Math.Ceiling(yn)));
}
}
else
{
points.Add(new Point((int) Math.Round(xn), (int) Math.Truncate(yn)));
points.Add(new Point((int) Math.Round(xn), (int) Math.Truncate(yn) + 1));
}
}
}
points.Remove(from);
points.Remove(to);
return points.ToArray();
}