public int GetDistanceSquaredToArea(XPoint2 pnt, RMArea area, int minDist) { Debug.Assert(area.Built, "GetDistanceSquaredToArea() does not work for unbuilt areas"); int sizeX = Map.GetLength(0), sizeY = Map.GetLength(1); XRectangle range = area.ActiveArea; range.RestrictToWithin(new XRectangle(pnt.X, pnt.Y, 1, 1)); range.Inflate(minDist); range.RestrictToWithin(new XRectangle(0, 0, sizeX, sizeY)); int minDist2 = int.MaxValue; for (int x = range.Left; x < range.Right; ++x) { for (int y = range.Top; y < range.Bottom; ++y) { int dx = x - pnt.X, dy = y - pnt.Y; int dist2 = dx * dx + dy * dy; if (dist2 > minDist * minDist) { continue; } if (Map[x, y] == area) { if (dist2 < minDist2) { minDist2 = dist2; } } } } return(minDist2); }
public void WithAreaTiles(Action <XPoint2, int> onTile, int minDistance, int maxDistance) { var map = Map; XRectangle range = activeArea; //range.Inflate(maxDistance); range.RestrictToWithin(new XRectangle(0, 0, Map.GetLength(0), Map.GetLength(1))); CalculateDistances(minDistance - 1, maxDistance + 1); for (int y = range.Top; y < range.Bottom; ++y) { for (int x = range.Left; x < range.Right; ++x) { int dist = map[x, y].Weight / 70; if (dist >= minDistance) { onTile(new XPoint2(x, y), dist); } } } }
void CalculateDistances(int minDistance, int maxDistance) { var map = Map; XRectangle range = activeArea; XRectangle mapRect = new XRectangle(0, 0, Map.GetLength(0), Map.GetLength(1)); range.Inflate(maxDistance); range.RestrictToWithin(mapRect); List <XPoint2> stack = new List <XPoint2>(); for (int y = range.Top; y < range.Bottom; ++y) { for (int x = range.Left; x < range.Right; ++x) { int minDist = int.MaxValue; for (int o = 0; o < propogOffs.Length; ++o) { XPoint2 off = propogOffs[o]; if (!mapRect.Contains(new XPoint2(x + off.X, y + off.Y))) { continue; } if (map[x + off.X, y + off.Y].IsPositive != map[x, y].IsPositive) { int newCost = propogCost[o]; minDist = Math.Min(minDist, newCost); } } if (minDist < int.MaxValue) { stack.Add(new XPoint2(x, y)); map[x, y].Weight = (map[x, y].IsPositive ? 70 : 70 - minDist); } else { map[x, y].Weight = (map[x, y].IsPositive ? maxDistance * 70 : minDistance * 70); } } } while (stack.Count > 0) { int count = stack.Count; for (int s = 0; s < count; ++s) { var pnt = stack[s]; var node = map[pnt.X, pnt.Y]; for (int o = 0; o < propogOffs.Length; ++o) { var newP = pnt + propogOffs[o]; if (!mapRect.Contains(newP)) { continue; } var tnode = map[newP.X, newP.Y]; if (node.IsPositive != tnode.IsPositive) { continue; } int newCost = node.Weight + (node.IsPositive ? propogCost[o] : -propogCost[o]); if (Math.Abs(newCost) < Math.Abs(tnode.Weight)) { map[newP.X, newP.Y].Weight = newCost; stack.Add(newP); } } } stack.RemoveRange(0, count); } }