I have been trying to create a Bresenhams line algorithm that preserves order so that the user is able to draw on a grid at runtime.
It works 'for the most part, however, it seems to get stuck in a while loop and crashes my program occasionally. I believe this is when the mouse is moving quite fast.
public static IEnumerable<WorldTile> GetWorldTilesOnLine(int x0, int y0, int x1, int y1)
{
int dy = (int)(y1-y0);
int dx = (int)(x1-x0);
int xstep = 1;
int ystep = 1;
if (dy < 0) {dy = -dy; xstep = -1;}
else {ystep = 1;}
if (dx < 0) {dx = -dx; ystep = -1;}
else {xstep = 1;}
dy <<= 1;
dx <<= 1;
float fraction = 0;
//Debug.Log (xstep);
if (x0 >= 0 && x0 < worldBoard.GetLength(0) && y0 >= 0 && y0 < worldBoard.GetLength(1))
{
yield return worldBoard[x0, y0];
}
if (dx > dy) {
fraction = dy - (dx >> 1);
while (Mathf.Abs(x0 - x1) > 1) { // This seems to be where the crash occurs
if (fraction >= 0) {
y0 += ystep;
fraction -= dx;
}
x0 += xstep;
fraction += dy;
if (x0 >= 0 && x0 < worldBoard.GetLength(0) && y0 >= 0 && y0 < worldBoard.GetLength(1))
{
yield return worldBoard[x0, y0];
}
}
}
else {
fraction = dx - (dy >> 1);
while (Mathf.Abs(y0 - y1) > 1) { // This seems to be where the crash occurs
if (fraction >= 0) {
x0 += xstep;
fraction -= dy;
}
y0 += ystep;
fraction += dx;
if (x0 >= 0 && x0 < worldBoard.GetLength(0) && y0 >= 0 && y0 < worldBoard.GetLength(1))
{
yield return worldBoard[x0, y0];
}
}
}
yield break;
}
This method is called while the user has the mouse button down using this
IEnumerator Draw()
{
startPos = WorldGridUtilities.getNearestWorldTileArrayValue(getMousePosition());
worldTilesToAdd = new List<WorldTile>();
Debug.Log (worldTilesToAdd.Count);
while (true)
{
worldTilesToAdd.Clear();
nextPos = WorldGridUtilities.getNearestWorldTileArrayValue(getMousePosition());
if (nextPos != startPos)
{
foreach (WorldTile wt in WorldGridUtilities.GetWorldTilesOnLine((int)startPos.x,(int)startPos.y, (int)nextPos.x, (int)nextPos.y))
{
worldTilesToAdd.Add (wt);
startPos = nextPos;
}
foreach (WorldTile wt in worldTilesToAdd)
{
//Debug.Log ("coordinates added to list used by vectorline: " + wt.gridCoordinates);
vectorLine.points3.Add(wt.gridCoordinates);
vectorLine.Draw3D();
}
yield return new WaitForEndOfFrame();
}
}