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