2020-01-23 21:08:01 +00:00
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace SemiColinGames {
|
2020-03-09 16:48:10 +00:00
|
|
|
|
public static class Line {
|
2020-01-23 21:08:01 +00:00
|
|
|
|
public static Point[] Rasterize(Point p1, Point p2) {
|
|
|
|
|
return Line.Rasterize(p1.X, p1.Y, p2.X, p2.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rasterizes a line using Bresenham's line-drawing algorithm.
|
|
|
|
|
//
|
|
|
|
|
// References:
|
|
|
|
|
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
|
|
|
|
|
// http://members.chello.at/~easyfilter/bresenham.html
|
|
|
|
|
// http://members.chello.at/~easyfilter/Bresenham.pdf (section 1.6)
|
|
|
|
|
public static Point[] Rasterize(int x1, int y1, int x2, int y2) {
|
|
|
|
|
int dx = Math.Abs(x2 - x1);
|
|
|
|
|
int stepX = x1 < x2 ? 1 : -1;
|
|
|
|
|
int dy = -Math.Abs(y2 - y1);
|
|
|
|
|
int stepY = y1 < y2 ? 1 : -1;
|
|
|
|
|
int error = dx + dy;
|
2020-01-25 02:09:09 +00:00
|
|
|
|
int errorXY; // Error value e_xy from the PDF.
|
2020-01-23 21:08:01 +00:00
|
|
|
|
// The size of the output is the size of the longer dimension, plus one.
|
|
|
|
|
int resultSize = Math.Max(dx, -dy) + 1;
|
2020-03-18 15:11:40 +00:00
|
|
|
|
// TODO: an array or list should be passed in by the caller.
|
2020-01-23 21:08:01 +00:00
|
|
|
|
var result = new Point[resultSize];
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
result[0] = new Point(x1, y1);
|
|
|
|
|
while (x1 != x2 || y1 != y2) {
|
|
|
|
|
i++;
|
|
|
|
|
errorXY = 2 * error;
|
|
|
|
|
if (errorXY >= dy) { // e_xy + e_x > 0
|
|
|
|
|
error += dy;
|
|
|
|
|
x1 += stepX;
|
|
|
|
|
}
|
|
|
|
|
if (errorXY <= dx) { // e_xy + e_y < 0
|
|
|
|
|
error += dx;
|
|
|
|
|
y1 += stepY;
|
|
|
|
|
}
|
|
|
|
|
result[i] = new Point(x1, y1);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|