X-Git-Url: https://git.ao2.it/flexagon-toolkit.git/blobdiff_plain/de12520337565607ec65190f8c83ba8aa8edfef6..d7db3a7d7112d2bf77c96d0f027bf0e00ab15215:/src/flexagon/tritetraflexagon.py diff --git a/src/flexagon/tritetraflexagon.py b/src/flexagon/tritetraflexagon.py new file mode 100755 index 0000000..8a70069 --- /dev/null +++ b/src/flexagon/tritetraflexagon.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# A generic model for a tri-tetraflexagon +# +# Copyright (C) 2018 Antonio Ospite +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from math import pi + + +class Tile(object): + def __init__(self, square, index): + self.square = square + self.index = index + + @staticmethod + def calc_plan_coordinates(side, i, j): + xoffset = side / 2 + j * side + yoffset = side / 2 + i * side + + return xoffset, yoffset + + @staticmethod + def calc_angle_in_plan(i, j): + """The angle of a tile in the tetraflexagon plan.""" + return pi * (i > 1) + + def __str__(self): + return "%d,%d" % (self.square.index, self.index) + + +class Square(object): + def __init__(self, index): + self.index = index + self.tiles = [] + for i in range(4): + tile = Tile(self, i) + self.tiles.append(tile) + + def __str__(self): + output = "" + for i in range(0, 4): + output += str(self.tiles[i]) + output += "\t" + + return output + + +class TriTetraflexagon(object): + def __init__(self): + self.squares = [] + for i in range(0, 3): + square = Square(i) + self.squares.append(square) + + # A plan is described by a mapping of the tiles in the squares, + # repositioned on a 2d grid. + # + # In the map below, the grid has two rows, each element of the grid is + # a pair (s, t), where 's' is the index of the square, and 't' is the + # index of the tile in that square. + plan_map = [ + [(2, 0), (2, 1), (0, 1), None, None], + [None, None, (0, 3), (1, 2), (1, 3)], + [None, None, (2, 3), (2, 2), (0, 2)], + [(0, 0), (1, 1), (1, 0), None, None], + ] + + # Preallocate a bi-dimensional array for an inverse mapping, this is + # useful to retrieve the position in the plan given a tile. + self.plan_map_inv = [[-1 for t in h.tiles] for h in self.squares] + + self.plan = [] + for i, plan_map_row in enumerate(plan_map): + plan_row = [] + for j, mapping in enumerate(plan_map_row): + if mapping: + square_index, tile_index = mapping + square = self.squares[square_index] + tile = square.tiles[tile_index] + self.plan_map_inv[square_index][tile_index] = (i, j) + else: + tile = None + + plan_row.append(tile) + + self.plan.append(plan_row) + + def get_tile_plan_position(self, tile): + return self.plan_map_inv[tile.square.index][tile.index] + + def __str__(self): + output = "" + + for row in self.plan: + for tile in row: + output += "%s\t" % str(tile) + output += "\n" + + return output + + +def test(): + tritetraflexagon = TriTetraflexagon() + print(tritetraflexagon) + + +if __name__ == "__main__": + test()