106 lines
4.4 KiB
Python
106 lines
4.4 KiB
Python
from Enums import DIRECTION
|
|
from gdpc import Editor, Block, geometry
|
|
from buildings.geometry.Tile import Tile
|
|
from buildings.geometry.Point import Point
|
|
from buildings.geometry.Rectangle import Rectangle
|
|
from buildings.geometry.Vertice import Vertice
|
|
|
|
class Polygon:
|
|
def __init__(self, position : Point, size: tuple[int,int]):
|
|
self.position = position
|
|
self.size = size
|
|
self.shape = []
|
|
self.vertices = []
|
|
|
|
def fill_polygon(self, editor : Editor, material : str, y : int, y2 : int = None):
|
|
if y2 == None: y2 = y
|
|
for rect in self.shape:
|
|
rect.fill(editor, material, y, y2)
|
|
|
|
def fill_vertice(self, editor : Editor, material : str, y : int, y2 : int = None):
|
|
if y2 == None: y2 = y
|
|
for vertice in self.vertices:
|
|
vertice.fill(editor, Block(material), y, y2)
|
|
|
|
def compress(self, tiles : list[Tile], vertices : list[Vertice]):
|
|
remaining_tiles = tiles.copy()
|
|
while len(remaining_tiles) > 0:
|
|
start = remaining_tiles[0]
|
|
neightbor = start.get_neighbor(DIRECTION.WEST)
|
|
row = []
|
|
|
|
# Find western border
|
|
while neightbor:
|
|
start = neightbor
|
|
neightbor = start.get_neighbor(DIRECTION.WEST)
|
|
|
|
# Find eastern border
|
|
while True:
|
|
row.append(start)
|
|
remaining_tiles.remove(start)
|
|
neightbor = start.get_neighbor(DIRECTION.EAST)
|
|
if not neightbor: break
|
|
start = neightbor
|
|
|
|
# Find northern border
|
|
north_row = self._find_row_border(row.copy(), DIRECTION.NORTH, remaining_tiles)
|
|
# Find southern border
|
|
south_row = self._find_row_border(row.copy(), DIRECTION.SOUTH, remaining_tiles)
|
|
|
|
area = Rectangle(north_row[0].north_west, south_row[-1].south_east)
|
|
self.shape.append(area)
|
|
|
|
remaining_vertices = vertices.copy()
|
|
current = remaining_vertices.pop()
|
|
while len(remaining_vertices) > 0:
|
|
neighbors = current.get_neighbors()
|
|
has_next1 = self._has_next(neighbors[0], current.facing, remaining_vertices)
|
|
has_next2 = self._has_next(neighbors[1], current.facing, remaining_vertices)
|
|
|
|
if has_next1:
|
|
current = Vertice(has_next1.point1, current.point2, current.facing)
|
|
elif has_next2:
|
|
current = Vertice(current.point1, has_next2.point2, current.facing)
|
|
else:
|
|
self.vertices.append(current)
|
|
current = remaining_vertices.pop()
|
|
|
|
if len(remaining_vertices) == 0: self.vertices.append(current)
|
|
|
|
def set_vertices_and_neighbors(self, tiles : list[Tile], vertices : list[Vertice]):
|
|
for tile in tiles:
|
|
targets = tile.get_neighbors_coords()
|
|
for vertice_num,target in enumerate(targets):
|
|
has_neighbor = self._has_neighbor(target, tiles)
|
|
if not has_neighbor:
|
|
vertice = tile.get_vertice(vertice_num)
|
|
vertices.append(vertice)
|
|
tile.set_vertice(DIRECTION(vertice_num), vertice)
|
|
else :
|
|
tile.set_neighbor(vertice_num, has_neighbor)
|
|
|
|
def _find_row_border(self, line : list[Tile], direction : str, remaining_tiles : list[Tile]) -> list[Tile]:
|
|
while True:
|
|
new_line = []
|
|
for tile in line:
|
|
neightbor = tile.get_neighbor(direction)
|
|
if neightbor not in remaining_tiles: return line
|
|
new_line.append(neightbor)
|
|
for tile in new_line: remaining_tiles.remove(tile)
|
|
line = new_line
|
|
|
|
def _has_neighbor(self, target : tuple[int], tiles : list[Tile]) -> bool|Tile:
|
|
for tile in tiles:
|
|
if tile.pos.position == target.position:
|
|
return tile
|
|
return False
|
|
|
|
def _has_next(self, target : Point, facing : str, remaining_vertices : list[Vertice]) -> bool|Vertice:
|
|
for vertice in remaining_vertices:
|
|
if vertice.facing == facing:
|
|
if vertice.point1.position == target.position or vertice.point2.position == target.position:
|
|
remaining_vertices.remove(vertice)
|
|
return vertice
|
|
return False
|
|
|
|
|