Grid(): make use of the fact that Coordinate is a tupple for some speedups
All checks were successful
Publish to PyPI / Publish to PyPI (push) Successful in 1m18s

This commit is contained in:
Stefan Harmuth 2023-12-14 16:18:25 +01:00
parent 32c07d2913
commit 2de9725adb
2 changed files with 48 additions and 48 deletions

View File

@ -48,7 +48,7 @@ class Coordinate(tuple):
:return: Distance to Target
"""
if algorithm == DistanceAlgorithm.EUCLIDEAN:
if self.z is None:
if self[2] is None:
return sqrt(abs(self[0] - target[0]) ** 2 + abs(self[1] - target[1]) ** 2)
else:
return sqrt(
@ -57,7 +57,7 @@ class Coordinate(tuple):
+ abs(self[2] - target[2]) ** 2
)
elif algorithm == DistanceAlgorithm.CHEBYSHEV:
if self.z is None:
if self[2] is None:
return max(abs(target[0] - self[0]), abs(target[1] - self[1]))
else:
return max(
@ -67,7 +67,7 @@ class Coordinate(tuple):
)
elif algorithm == DistanceAlgorithm.MANHATTAN:
if not includeDiagonals:
if self.z is None:
if self[2] is None:
return abs(self[0] - target[0]) + abs(self[1] - target[1])
else:
return (
@ -77,7 +77,7 @@ class Coordinate(tuple):
)
else:
dist = [abs(self[0] - target[0]), abs(self[1] - target[1])]
if self.z is None:
if self[2] is None:
o_dist = max(dist) - min(dist)
return o_dist + 1.4 * min(dist)
else:
@ -97,7 +97,7 @@ class Coordinate(tuple):
minZ: int = -inf,
maxZ: int = inf,
) -> bool:
if self.z is None:
if self[2] is None:
return minX <= self[0] <= maxX and minY <= self[1] <= maxY
else:
return (
@ -118,7 +118,7 @@ class Coordinate(tuple):
maxZ: int = inf,
) -> list[Coordinate]:
ret = []
if self.z is None: # mode 2D
if self[2] is None: # mode 2D
for x in range(self[0] - radius * 2, self[0] + radius * 2 + 1):
for y in range(self[1] - radius * 2, self[1] + radius * 2 + 1):
target = Coordinate(x, y)
@ -171,7 +171,7 @@ class Coordinate(tuple):
:param maxZ: ignore all neighbours that would have an Z value above this
:return: list of Coordinate
"""
if self.z is None:
if self[2] is None:
if includeDiagonal:
nb_list = [
(-1, -1),
@ -218,7 +218,7 @@ class Coordinate(tuple):
def getAngleTo(self, target: Coordinate | tuple, normalized: bool = False) -> float:
"""normalized returns an angle going clockwise with 0 starting in the 'north'"""
if self.z is not None:
if self[2] is not None:
raise NotImplementedError() # which angle?!?!
dx = target[0] - self[0]
@ -235,7 +235,7 @@ class Coordinate(tuple):
def getLineTo(self, target: Coordinate | tuple) -> List[Coordinate]:
diff = target - self
if self.z is None:
if self[2] is None:
steps = gcd(diff[0], diff[0])
step_x = diff[0] // steps
step_y = diff[1] // steps
@ -256,31 +256,31 @@ class Coordinate(tuple):
]
def reverse(self) -> Coordinate:
if self.z is None:
if self[2] is None:
return self.__class__(-self[0], -self[1])
else:
return self.__class__(-self[0], -self[1], -self[2])
def __add__(self, other: Coordinate | tuple) -> Coordinate:
if self.z is None:
if self[2] is None:
return self.__class__(self[0] + other[0], self[1] + other[1])
else:
return self.__class__(self[0] + other[0], self[1] + other[1], self[2] + other[2])
def __sub__(self, other: Coordinate | tuple) -> Coordinate:
if self.z is None:
if self[2] is None:
return self.__class__(self[0] - other[0], self[1] - other[1])
else:
return self.__class__(self[0] - other[0], self[1] - other[1], self[2] - other[2])
def __mul__(self, other: int) -> Coordinate:
if self.z is None:
if self[2] is None:
return self.__class__(self[0] * other, self[1] * other)
else:
return self.__class__(self[0] * other, self[1] * other, self[2] * other)
def __floordiv__(self, other: int | float) -> Coordinate:
if self.z is None:
if self[2] is None:
return self.__class__(self[0] // other, self[1] // other)
else:
return self.__class__(self[0] // other, self[1] // other, self[2] // other)
@ -289,13 +289,13 @@ class Coordinate(tuple):
return self // other
def __str__(self):
if self.z is None:
if self[2] is None:
return "(%d,%d)" % (self[0], self[1])
else:
return "(%d,%d,%d)" % (self[0], self[1], self[2])
def __repr__(self):
if self.z is None:
if self[2] is None:
return "%s(x=%d, y=%d)" % (self.__class__.__name__, self[0], self[1])
else:
return "%s(x=%d, y=%d, z=%d)" % (

View File

@ -48,19 +48,19 @@ class Grid:
def __trackBoundaries(self, pos: Coordinate):
if self.minX is None:
self.minX, self.maxX, self.minY, self.maxY = pos.x, pos.x, pos.y, pos.y
self.minX, self.maxX, self.minY, self.maxY = pos[0], pos[0], pos[1], pos[1]
else:
self.minX = pos.x if pos.x < self.minX else self.minX
self.minY = pos.y if pos.y < self.minY else self.minY
self.maxX = pos.x if pos.x > self.maxX else self.maxX
self.maxY = pos.y if pos.y > self.maxY else self.maxY
self.minX = pos[0] if pos[0] < self.minX else self.minX
self.minY = pos[1] if pos[1] < self.minY else self.minY
self.maxX = pos[0] if pos[0] > self.maxX else self.maxX
self.maxY = pos[1] if pos[1] > self.maxY else self.maxY
if self.mode3D:
if self.minZ is None:
self.minZ = self.maxZ = pos.z
self.minZ = self.maxZ = pos[2]
else:
self.minZ = pos.z if pos.z < self.minZ else self.minZ
self.maxZ = pos.z if pos.z > self.maxZ else self.maxZ
self.minZ = pos[2] if pos[2] < self.minZ else self.minZ
self.maxZ = pos[2] if pos[2] > self.maxZ else self.maxZ
def recalcBoundaries(self) -> None:
self.minX, self.maxX, self.minY, self.maxY, self.minZ, self.maxZ = (
@ -123,7 +123,7 @@ class Grid:
self.toggle(Coordinate(x, y, z))
def set(self, pos: Coordinate, value: Any = True) -> Any:
if pos.z is not None:
if pos[2] is not None:
self.mode3D = True
if (value == self.__default) and pos in self.__grid:
@ -157,13 +157,13 @@ class Grid:
return self.set(pos, self.get(pos) / value)
def add_shape(self, shape: Shape, value: int | float = 1) -> None:
for x in range(shape.top_left.x, shape.bottom_right.x + 1):
for y in range(shape.top_left.y, shape.bottom_right.y + 1):
for x in range(shape.top_left[0], shape.bottom_right[0] + 1):
for y in range(shape.top_left[1], shape.bottom_right[1] + 1):
if not shape.mode_3d:
pos = Coordinate(x, y)
self.set(pos, self.get(pos) + value)
else:
for z in range(shape.top_left.z, shape.bottom_right.z + 1):
for z in range(shape.top_left[2], shape.bottom_right[2] + 1):
pos = Coordinate(x, y, z)
self.set(pos, self.get(pos) + value)
@ -205,14 +205,14 @@ class Grid:
def isWithinBoundaries(self, pos: Coordinate, pad: int = 0) -> bool:
if self.mode3D:
return (
self.minX + pad <= pos.x <= self.maxX - pad
and self.minY + pad <= pos.y <= self.maxY - pad
and self.minZ + pad <= pos.z <= self.maxZ - pad
self.minX + pad <= pos[0] <= self.maxX - pad
and self.minY + pad <= pos[1] <= self.maxY - pad
and self.minZ + pad <= pos[2] <= self.maxZ - pad
)
else:
return (
self.minX + pad <= pos.x <= self.maxX - pad
and self.minY + pad <= pos.y <= self.maxY - pad
self.minX + pad <= pos[0] <= self.maxX - pad
and self.minY + pad <= pos[1] <= self.maxY - pad
)
def getActiveCells(
@ -222,9 +222,9 @@ class Grid:
return (
c
for c in self.__grid.keys()
if (c.x == x if x is not None else True)
and (c.y == y if y is not None else True)
and (c.z == z if z is not None else True)
if (c[0] == x if x is not None else True)
and (c[1] == y if y is not None else True)
and (c[2] == z if z is not None else True)
)
else:
return self.__grid.keys()
@ -271,7 +271,7 @@ class Grid:
pos: Coordinate,
includeDefault: bool = False,
includeDiagonal: bool = True,
) -> List[Coordinate]:
) -> Iterable[Coordinate]:
neighbours = pos.getNeighbours(
includeDiagonal=includeDiagonal,
minX=self.minX,
@ -312,47 +312,47 @@ class Grid:
if mode == GridTransformation.ROTATE_X:
shift_z = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.x, c.z, -c.y), v)
self.set(Coordinate(c[0], c[2], -c[1]), v)
self.shift(shift_z=shift_z)
elif mode == GridTransformation.ROTATE_Y:
shift_x = self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.z, c.y, c.x), v)
self.set(Coordinate(-c[2], c[1], c[0]), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.ROTATE_Z:
shift_x = self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.y, c.x, c.z), v)
self.set(Coordinate(-c[1], c[0], c[2]), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.COUNTER_ROTATE_X:
shift_y = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.x, -c.z, c.y), v)
self.set(Coordinate(c[0], -c[2], c[1]), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.COUNTER_ROTATE_Y:
shift_z = self.maxZ
for c, v in coords.items():
self.set(Coordinate(c.z, c.y, -c.x), v)
self.set(Coordinate(c[2], c[1], -c[0]), v)
self.shift(shift_z=shift_z)
elif mode == GridTransformation.COUNTER_ROTATE_Z:
shift_y = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.y, -c.x, c.z), v)
self.set(Coordinate(c[1], -c[0], c[2]), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.FLIP_X:
shift_x = self.maxX
for c, v in coords.items():
self.set(Coordinate(-c.x, c.y, c.z), v)
self.set(Coordinate(-c[0], c[1], c[2]), v)
self.shift(shift_x=shift_x)
elif mode == GridTransformation.FLIP_Y:
shift_y = self.maxY
for c, v in coords.items():
self.set(Coordinate(c.x, -c.y, c.z), v)
self.set(Coordinate(c[0], -c[1], c[2]), v)
self.shift(shift_y=shift_y)
elif mode == GridTransformation.FLIP_Z:
shift_z = self.maxZ
for c, v in coords.items():
self.set(Coordinate(c.x, c.y, -c.z), v)
self.set(Coordinate(c[0], c[1], -c[2]), v)
self.shift(shift_z=shift_z)
else:
raise NotImplementedError(mode)
@ -368,9 +368,9 @@ class Grid:
self.__grid = {}
for c, v in coords.items():
if self.mode3D:
nc = Coordinate(c.x + shift_x, c.y + shift_y, c.z + shift_z)
nc = Coordinate(c[0] + shift_x, c[1] + shift_y, c[2] + shift_z)
else:
nc = Coordinate(c.x + shift_x, c.y + shift_y)
nc = Coordinate(c[0] + shift_x, c[1] + shift_y)
self.set(nc, v)
def shift_zero(self, recalc: bool = True):