Grid.transform() in 3D!

This commit is contained in:
Stefan Harmuth 2021-12-19 16:26:50 +01:00
parent 74df9e9287
commit d8d7112098
2 changed files with 58 additions and 42 deletions

View File

@ -1,23 +1,33 @@
from __future__ import annotations from __future__ import annotations
from .coordinate import Coordinate, DistanceAlgorithm from .coordinate import Coordinate, DistanceAlgorithm
from .types import Numeric
from enum import Enum from enum import Enum
from heapq import heappop, heappush from heapq import heappop, heappush
from typing import Any, Dict, List, Union from typing import Any, Dict, List, Union
OFF = False OFF = False
ON = True ON = True
Numeric = Union[int, float]
class GridTransformation(Enum): class GridTransformation(Enum):
FLIP_X = 1 # Rotations always take the axis to rotate around as if it were the z-axis and then rotate clockwise
FLIP_HORIZONTALLY = 1 # alias for FLIP_X; prep for 3d-transformations # Counter-Rotations likewise, just anti-clockwise
FLIP_VERTICALLY = 2 # 3D-only OPs have a number > 10
FLIP_DIAGONALLY = 3 ROTATE_Z = 3
FLIP_DIAGONALLY_REV = 4 ROTATE_X = 11
ROTATE_RIGHT = 5 ROTATE_Y = 12
ROTATE_LEFT = 6 COUNTER_ROTATE_X = 14
ROTATE_TWICE = 7 COUNTER_ROTATE_Y = 15
COUNTER_ROTATE_Z = 7
FLIP_X = 4
FLIP_Y = 5
FLIP_Z = 13
# Handy aliases
FLIP_HORIZONTALLY = 5
FLIP_VERTICALLY = 4
ROTATE_RIGHT = 3
ROTATE_LEFT = 7
class Grid: class Grid:
@ -162,40 +172,40 @@ class Grid:
self.set(c2, buf) self.set(c2, buf)
def transform(self, mode: GridTransformation): def transform(self, mode: GridTransformation):
if self.mode3D: if mode.value > 10 and not self.mode3D:
raise NotImplementedError() # that will take some time and thought raise ValueError("Operation not possible in 2D space", mode)
if mode == GridTransformation.FLIP_HORIZONTALLY: coords = self.__grid
for x in range(self.minX, (self.maxX - self.minX) // 2 + 1): self.__grid, self.minX, self.maxX, self.minY, self.maxY, self.minZ, self.maxZ = {}, 0, 0, 0, 0, 0, 0
for y in range(self.minY, self.maxY + 1): if mode == GridTransformation.ROTATE_X:
self.flip(Coordinate(x, y), Coordinate(self.maxX - x, y)) for c, v in coords.items():
elif mode == GridTransformation.FLIP_VERTICALLY: self.set(Coordinate(c.x, -c.z, c.y), v)
for y in range(self.minY, (self.maxY - self.minY) // 2 + 1): elif mode == GridTransformation.ROTATE_Y:
for x in range(self.minX, self.maxX + 1): for c, v in coords.items():
self.flip(Coordinate(x, y), Coordinate(x, self.maxY - y)) self.set(Coordinate(-c.z, c.y, c.x), v)
elif mode == GridTransformation.FLIP_DIAGONALLY: elif mode == GridTransformation.ROTATE_Z:
self.transform(GridTransformation.ROTATE_LEFT) for c, v in coords.items():
self.transform(GridTransformation.FLIP_HORIZONTALLY) self.set(Coordinate(c.y, -c.x, c.z), v)
elif mode == GridTransformation.FLIP_DIAGONALLY_REV: elif mode == GridTransformation.COUNTER_ROTATE_X:
self.transform(GridTransformation.ROTATE_RIGHT) for c, v in coords.items():
self.transform(GridTransformation.FLIP_HORIZONTALLY) self.set(Coordinate(c.x, c.z, -c.y), v)
elif mode == GridTransformation.ROTATE_LEFT: elif mode == GridTransformation.COUNTER_ROTATE_Y:
newGrid = Grid() for c, v in coords.items():
for x in range(self.maxX, self.minX - 1, -1): self.set(Coordinate(c.z, c.y, -c.x), v)
for y in range(self.minY, self.maxY + 1): elif mode == GridTransformation.COUNTER_ROTATE_Z:
newGrid.set(Coordinate(y, self.maxX - x), self.get(Coordinate(x, y))) for c, v in coords.items():
self.set(Coordinate(-c.y, c.x, c.z), v)
self.__dict__.update(newGrid.__dict__) elif mode == GridTransformation.FLIP_X:
elif mode == GridTransformation.ROTATE_RIGHT: for c, v in coords.items():
newGrid = Grid() self.set(Coordinate(-c.x, c.y, c.z), v)
for x in range(self.minX, self.maxX + 1): elif mode == GridTransformation.FLIP_Y:
for y in range(self.maxY, self.minY - 1, -1): for c, v in coords.items():
newGrid.set(Coordinate(self.maxY - y, x), self.get(Coordinate(x, y))) self.set(Coordinate(c.x, -c.y, c.z), v)
elif mode == GridTransformation.FLIP_Z:
self.__dict__.update(newGrid.__dict__) for c, v in coords.items():
elif mode == GridTransformation.ROTATE_TWICE: self.set(Coordinate(c.x, c.y, -c.z), v)
self.transform(GridTransformation.ROTATE_RIGHT) else:
self.transform(GridTransformation.ROTATE_RIGHT) raise NotImplementedError(mode)
def getPath(self, pos_from: Coordinate, pos_to: Coordinate, includeDiagonal: bool, walls: List[Any] = None, def getPath(self, pos_from: Coordinate, pos_to: Coordinate, includeDiagonal: bool, walls: List[Any] = None,
weighted: bool = False) -> Union[None, List[Coordinate]]: weighted: bool = False) -> Union[None, List[Coordinate]]:

6
tools/types.py Normal file
View File

@ -0,0 +1,6 @@
from typing import Union
Numeric = Union[int, float]
IntOrNone = Union[int, None]
FloatOrNone = Union[float, None]
NumericOrNone = Union[Numeric, None]