From 987a5bab288801611d477e28e9cb18a57d67164f Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Sun, 14 Aug 2022 13:25:33 +0200 Subject: [PATCH] better dealing with boundaries getting circles (mind the FIXME) --- tools/coordinate.py | 32 ++++++++++++++++++++++++++++++++ tools/grid.py | 7 +++++++ 2 files changed, 39 insertions(+) diff --git a/tools/coordinate.py b/tools/coordinate.py index de3edc3..7fce03c 100644 --- a/tools/coordinate.py +++ b/tools/coordinate.py @@ -59,6 +59,38 @@ class Coordinate: o_dist = max(dist) - min(dist) return 1.7 * d_steps + o_dist + 1.4 * min(dist) + def inBoundaries(self, minX: int, minY: int, maxX: int, maxY: int, minZ: int = -inf, maxZ: int = inf) -> bool: + if self.z is None: + return minX <= self.x <= maxX and minY <= self.y <= maxY + else: + return minX <= self.x <= maxX and minY <= self.y <= maxY and minZ <= self.z <= maxZ + + def getCircle(self, radius: int = 1, includeDiagonal: bool = True, minX: int = -inf, minY: int = -inf, + maxX: int = inf, maxY: int = inf, minZ: int = -inf, maxZ: int = inf) -> list[Coordinate]: + # FIXME: includeDiagonal == True returns way too few coordinates + ret = [] + if self.z is None: # mode 2D + for x in range(self.x - radius * 2, self.x + radius * 2 + 1): + for y in range(self.y - radius * 2, self.y + radius * 2 + 1): + target = Coordinate(x, y) + if not target.inBoundaries(minX, minY, maxX, maxY): + continue + dist = self.getDistanceTo(target, DistanceAlgorithm.MANHATTAN, includeDiagonals=includeDiagonal) + if dist == radius: + ret.append(target) + else: + for x in range(self.x - radius * 2, self.x + radius * 2 + 1): + for y in range(self.y - radius * 2, self.y + radius * 2 + 1): + for z in range(self.z - radius * 2, self.z + radius * 2 + 1): + target = Coordinate(x, y) + if not target.inBoundaries(minX, minY, maxX, maxY, minZ, maxZ): + continue + dist = self.getDistanceTo(target, DistanceAlgorithm.MANHATTAN, includeDiagonals=includeDiagonal) + if dist == radius: + ret.append(target) + + return ret + def getNeighbours(self, includeDiagonal: bool = True, minX: int = -inf, minY: int = -inf, maxX: int = inf, maxY: int = inf, minZ: int = -inf, maxZ: int = inf) -> list[Coordinate]: """ diff --git a/tools/grid.py b/tools/grid.py index 7a5863b..825d7b7 100644 --- a/tools/grid.py +++ b/tools/grid.py @@ -3,6 +3,7 @@ from .coordinate import Coordinate, DistanceAlgorithm, Shape from .types import Numeric from enum import Enum from heapq import heappop, heappush +from math import inf from typing import Any, Dict, List, Union OFF = False @@ -58,6 +59,12 @@ class Grid: self.minZ = pos.z if pos.z < self.minZ else self.minZ self.maxZ = pos.z if pos.z > self.maxZ else self.maxZ + def getBoundaries(self) -> (int, int, int, int, int, int): + if self.mode3D: + return self.minX, self.minY, self.maxX, self.maxY, self.minZ, self.maxZ + else: + return self.minX, self.minY, self.maxX, self.maxY, -inf, inf + def rangeX(self, pad: int = 0, reverse=False): if reverse: return range(self.maxX + pad, self.minX - pad - 1, -1)