simetri.canvas.grids

Provides facilities for working with grids of cells.

  1"""Provides facilities for working with grids of cells."""
  2
  3from itertools import product
  4from math import sin, cos, pi, sqrt
  5from typing import Sequence
  6
  7from numpy import isclose
  8
  9from ..helpers.utilities import reg_poly_points
 10from ..geometry.geometry import (
 11    intersect,
 12    cartesian_to_polar,
 13    polar_to_cartesian,
 14    lerp_point,
 15    distance
 16)
 17from ..geometry.circle import Circle
 18from ..graphics.common import Point, common_properties
 19from ..graphics.batch import Batch
 20from ..graphics.shape import Shape
 21from ..graphics.all_enums import Types, GridType
 22from ..colors.colors import gray
 23
 24
 25d_grid_types = {
 26    GridType.CIRCULAR: Types.CIRCULAR_GRID,
 27    GridType.SQUARE: Types.SQUARE_GRID,
 28    GridType.HEXAGONAL: Types.HEX_GRID,
 29    GridType.MIXED: Types.MIXED_GRID,
 30}
 31
 32
 33class Grid(Batch):
 34    """A base-class for all grids."""
 35
 36    def __init__(
 37        self,
 38        grid_type: GridType,
 39        center: Point = (0, 0),
 40        n: int = 9,
 41        radius: float = 100,
 42        points: Sequence[Point] = None,
 43        n_circles=1,
 44    ):
 45        if grid_type not in d_grid_types:
 46            raise ValueError(f"Invalid grid type: {grid_type}.")
 47        super().__init__(subtype=d_grid_types[grid_type])
 48        common_properties(self)
 49        self.center = center
 50        self.radius = radius
 51        self.n = n
 52        self.n_circles = n_circles
 53        pairs = list(product(points, repeat=2))
 54
 55        self.points = points if points else []
 56        for i, point in enumerate(self.points):
 57                next_point = self.points[(i + 1) % len(self.points)]
 58                self.append(Shape([point, next_point]))
 59
 60        if grid_type == GridType.SQUARE:
 61            # Draw only the horizontal and vertical lines in the grid
 62            width = self.width
 63            for p1, p2 in pairs:
 64                x1, y1 = p1
 65                x2, y2 = p2
 66                cond1 = x1 == x2
 67                cond2 = y1 == y2
 68                if cond1 ^ cond2:
 69                    dist = distance(p1, p2)
 70                    if isclose(dist, width, rtol=0, atol=1e-5):
 71                        self.append(Shape([p1, p2], line_color=gray))
 72        else:
 73            # Draw the lines connecting the points in the grid
 74            for point1, point2 in pairs:
 75                if point1 != point2:
 76                    self.append(Shape([point1, point2], line_color=gray))
 77
 78    def intersect(self, line1: Sequence[int], line2: Sequence[int]):
 79        """
 80        Returns the intersection of the lines connecting the given indices.
 81
 82        Args:
 83            line1 (Sequence[int]): A sequence containing two indices (ind1, ind2).
 84            line2 (Sequence[int]): A sequence containing two indices (ind3, ind4).
 85
 86        Returns:
 87            tuple: (x, y) intersection point of the lines.
 88        """
 89        ind1, ind2 = line1
 90        ind3, ind4 = line2
 91
 92        line1 = (self.points[ind1], self.points[ind2])
 93        line2 = (self.points[ind3], self.points[ind4])
 94
 95        return intersect(line1, line2)
 96
 97    def line(self, ind1: int, ind2: int) -> tuple:
 98        """
 99        Returns the line connecting the given indices.
100
101        Args:
102            ind1 (int): The first index.
103            ind2 (int): The second index.
104
105        Returns:
106            tuple: The line connecting the two points.
107        """
108        return (self.points[ind1], self.points[ind2])
109
110    def radial_point(self, radius, index: int):
111        """
112        Returns the point on the line connecting the center of the grid to the given index.
113        radius is the distance from the center to the point.
114        The index is the index of the point in the grid.
115
116        Args:
117            radius (float): The radius.
118            index (int): The index of the point.
119
120        Returns:
121            tuple: The polar point.
122        """
123        return polar_to_cartesian(radius, index * (2 * pi / self.n))
124
125    def between(self, ind1: int, ind2, t: float = 0.5) -> Point:
126        """
127        Returns the point on the line connecting the given indices interpolated
128        by using the given t parameter.
129
130        Args:
131            ind1 (int): The first index.
132            ind2 (int): The second index.
133            t (float): The parameter used for interpolation. Default is 0.5.
134
135        Returns:
136            Point: The point on the line connecting the two points.
137        """
138        if t < 0 or t > 1:
139            raise ValueError("t must be between 0 and 1.")
140        if ind1 < 0 or ind1 >= len(self.points):
141            raise ValueError(f"ind1 must be between 0 and {len(self.points) - 1}.")
142        if ind1 == ind2:
143            raise ValueError("ind1 and ind2 must be different.")
144
145        return lerp_point(self.points[ind1], self.points[ind2], t)
146
147
148class CircularGrid(Grid):
149    """A grid formed by connections of regular polygon points."""
150
151    def __init__(
152        self, center: Point = (0, 0), n: int = 12, radius: float = 100, n_circles=1
153    ):
154        """
155        Initializes the grid with the given center, radius, number of rows, and number of columns.
156
157        Args:
158            center (Point): The center point of the grid.
159            n (int): The number of points in the regular polygon.
160            radius (float): The radius of the grid.
161            n_circles (int): The number of circles in the grid. Used for drawing the grid.
162        """
163        points = reg_poly_points(center, n, radius)
164        super().__init__(GridType.CIRCULAR, center, n, radius, points, n_circles)
165
166        self.append(Circle(center, radius, fill=False))
167
168class HexGrid(Grid):
169    """A grid formed by connections of regular polygon points."""
170
171    def __init__(self, center: Point = (0, 0), radius: float = 100, n_circles=1):
172        """
173        Initializes the grid with the given center, radius, number of rows, and number of columns.
174
175        Args:
176            center (Point): The center point of the hexagon.
177            radius (float): The circumradius of the hexagon.
178            n_circles (int): The number of circles in the grid. Used for drawing the grid.
179        """
180        points = reg_poly_points(center, 6, radius)
181        super().__init__(GridType.HEXAGONAL, center, 6, radius, points, n_circles)
182
183
184class SquareGrid(Grid):
185    """A grid formed by connections of square cells."""
186
187    def __init__(self, center: Point = (0, 0), n: int = 16, cell_size: float = 25):
188        """
189        Initializes the grid with the given center, number of rows, number of columns, and cell size.
190
191        Args:
192            center (Point): The center point of the grid.
193            n (int): The number of points in the grid. Square of an even integer.
194            cell_size (float): The size of each cell in the grid.
195        """
196        self.cell_size = cell_size
197        self.width = cell_size * n / 4
198        hs = int(sqrt(n) // 2)  # half size
199        c = cell_size
200        vals = [c * x for x in range(-hs, hs + 1)]
201        coords = list(product(vals, repeat=2))
202
203        def sort_key(coord):
204            r, _ = cartesian_to_polar(*coord)
205            return r
206
207        def sort_key2(coord):
208            _, theta = cartesian_to_polar(*coord)
209            return theta
210
211        coords.sort(key=sort_key, reverse=True)
212        coords = coords[:n]
213        coords.sort(key=sort_key2)
214        points = coords
215        radius = (2 * (cell_size * sqrt(n))**2)**.5
216        super().__init__(GridType.SQUARE, center, n, radius, points)
217
218# change of basis conversion
219
220
221def convert_basis(x: float, y: float, basis: tuple):
222    """
223    Converts the given (x, y) coordinates from the standard basis to the given basis.
224
225    Args:
226        x (float): The x-coordinate.
227        y (float): The y-coordinate.
228        basis (tuple): The basis to convert to.
229
230    Returns:
231        tuple: The converted (x, y) coordinates.
232    """
233    return basis[0][0] * x + basis[0][1] * y, basis[1][0] * x + basis[1][1] * y
234
235
236def convert_to_cartesian(x: float, y: float, basis: tuple):
237    """
238    Converts the given (x, y) coordinates from the given basis to the standard basis.
239
240    Args:
241        x (float): The x-coordinate.
242        y (float): The y-coordinate.
243        basis (tuple): The basis to convert from.
244
245    Returns:
246        tuple: The converted (x, y) coordinates.
247    """
248    return basis[0][0] * x + basis[1][0] * y, basis[0][1] * x + basis[1][1] * y
249
250
251def cartesian_to_isometric(x: float, y: float):
252    """
253    Converts the given (x, y) coordinates to isometric coordinates.
254
255    Args:
256        x (float): The x-coordinate.
257        y (float): The y-coordinate.
258
259    Returns:
260        tuple: The isometric (x, y) coordinates.
261    """
262    return convert_basis(x, y, ((1, 0), (cos(pi / 3), sin(pi / 3))))
263
264
265def isometric_to_cartesian(x: float, y: float):
266    """
267    Converts the given isometric (x, y) coordinates to Cartesian coordinates.
268
269    Args:
270        x (float): The x-coordinate.
271        y (float): The y-coordinate.
272
273    Returns:
274        tuple: The Cartesian (x, y) coordinates.
275    """
276    return convert_to_cartesian(x, y, ((1, 0), (cos(pi / 3), sin(pi / 3))))
d_grid_types = {<GridType.CIRCULAR: 'CIRCULAR'>: <Types.CIRCULAR_GRID: 'CIRCULAR_GRID'>, <GridType.SQUARE: 'SQUARE'>: <Types.SQUARE_GRID: 'SQUARE_GRID'>, <GridType.HEXAGONAL: 'HEXAGONAL'>: <Types.HEX_GRID: 'HEX_GRID'>, <GridType.MIXED: 'MIXED'>: <Types.MIXED_GRID: 'MIXED_GRID'>}
class Grid(simetri.graphics.batch.Batch):
 34class Grid(Batch):
 35    """A base-class for all grids."""
 36
 37    def __init__(
 38        self,
 39        grid_type: GridType,
 40        center: Point = (0, 0),
 41        n: int = 9,
 42        radius: float = 100,
 43        points: Sequence[Point] = None,
 44        n_circles=1,
 45    ):
 46        if grid_type not in d_grid_types:
 47            raise ValueError(f"Invalid grid type: {grid_type}.")
 48        super().__init__(subtype=d_grid_types[grid_type])
 49        common_properties(self)
 50        self.center = center
 51        self.radius = radius
 52        self.n = n
 53        self.n_circles = n_circles
 54        pairs = list(product(points, repeat=2))
 55
 56        self.points = points if points else []
 57        for i, point in enumerate(self.points):
 58                next_point = self.points[(i + 1) % len(self.points)]
 59                self.append(Shape([point, next_point]))
 60
 61        if grid_type == GridType.SQUARE:
 62            # Draw only the horizontal and vertical lines in the grid
 63            width = self.width
 64            for p1, p2 in pairs:
 65                x1, y1 = p1
 66                x2, y2 = p2
 67                cond1 = x1 == x2
 68                cond2 = y1 == y2
 69                if cond1 ^ cond2:
 70                    dist = distance(p1, p2)
 71                    if isclose(dist, width, rtol=0, atol=1e-5):
 72                        self.append(Shape([p1, p2], line_color=gray))
 73        else:
 74            # Draw the lines connecting the points in the grid
 75            for point1, point2 in pairs:
 76                if point1 != point2:
 77                    self.append(Shape([point1, point2], line_color=gray))
 78
 79    def intersect(self, line1: Sequence[int], line2: Sequence[int]):
 80        """
 81        Returns the intersection of the lines connecting the given indices.
 82
 83        Args:
 84            line1 (Sequence[int]): A sequence containing two indices (ind1, ind2).
 85            line2 (Sequence[int]): A sequence containing two indices (ind3, ind4).
 86
 87        Returns:
 88            tuple: (x, y) intersection point of the lines.
 89        """
 90        ind1, ind2 = line1
 91        ind3, ind4 = line2
 92
 93        line1 = (self.points[ind1], self.points[ind2])
 94        line2 = (self.points[ind3], self.points[ind4])
 95
 96        return intersect(line1, line2)
 97
 98    def line(self, ind1: int, ind2: int) -> tuple:
 99        """
100        Returns the line connecting the given indices.
101
102        Args:
103            ind1 (int): The first index.
104            ind2 (int): The second index.
105
106        Returns:
107            tuple: The line connecting the two points.
108        """
109        return (self.points[ind1], self.points[ind2])
110
111    def radial_point(self, radius, index: int):
112        """
113        Returns the point on the line connecting the center of the grid to the given index.
114        radius is the distance from the center to the point.
115        The index is the index of the point in the grid.
116
117        Args:
118            radius (float): The radius.
119            index (int): The index of the point.
120
121        Returns:
122            tuple: The polar point.
123        """
124        return polar_to_cartesian(radius, index * (2 * pi / self.n))
125
126    def between(self, ind1: int, ind2, t: float = 0.5) -> Point:
127        """
128        Returns the point on the line connecting the given indices interpolated
129        by using the given t parameter.
130
131        Args:
132            ind1 (int): The first index.
133            ind2 (int): The second index.
134            t (float): The parameter used for interpolation. Default is 0.5.
135
136        Returns:
137            Point: The point on the line connecting the two points.
138        """
139        if t < 0 or t > 1:
140            raise ValueError("t must be between 0 and 1.")
141        if ind1 < 0 or ind1 >= len(self.points):
142            raise ValueError(f"ind1 must be between 0 and {len(self.points) - 1}.")
143        if ind1 == ind2:
144            raise ValueError("ind1 and ind2 must be different.")
145
146        return lerp_point(self.points[ind1], self.points[ind2], t)

A base-class for all grids.

Grid( grid_type: simetri.graphics.all_enums.GridType, center: Sequence[float] = (0, 0), n: int = 9, radius: float = 100, points: Sequence[Sequence[float]] = None, n_circles=1)
37    def __init__(
38        self,
39        grid_type: GridType,
40        center: Point = (0, 0),
41        n: int = 9,
42        radius: float = 100,
43        points: Sequence[Point] = None,
44        n_circles=1,
45    ):
46        if grid_type not in d_grid_types:
47            raise ValueError(f"Invalid grid type: {grid_type}.")
48        super().__init__(subtype=d_grid_types[grid_type])
49        common_properties(self)
50        self.center = center
51        self.radius = radius
52        self.n = n
53        self.n_circles = n_circles
54        pairs = list(product(points, repeat=2))
55
56        self.points = points if points else []
57        for i, point in enumerate(self.points):
58                next_point = self.points[(i + 1) % len(self.points)]
59                self.append(Shape([point, next_point]))
60
61        if grid_type == GridType.SQUARE:
62            # Draw only the horizontal and vertical lines in the grid
63            width = self.width
64            for p1, p2 in pairs:
65                x1, y1 = p1
66                x2, y2 = p2
67                cond1 = x1 == x2
68                cond2 = y1 == y2
69                if cond1 ^ cond2:
70                    dist = distance(p1, p2)
71                    if isclose(dist, width, rtol=0, atol=1e-5):
72                        self.append(Shape([p1, p2], line_color=gray))
73        else:
74            # Draw the lines connecting the points in the grid
75            for point1, point2 in pairs:
76                if point1 != point2:
77                    self.append(Shape([point1, point2], line_color=gray))

Initialize a Batch object.

Arguments:
  • elements (Sequence[Any], optional): The elements to include in the batch.
  • modifiers (Sequence[Modifier], optional): The modifiers to apply to the batch.
  • subtype (Types, optional): The subtype of the batch.
  • kwargs (dict): Additional keyword arguments.
center
radius
n
n_circles
points
def intersect(self, line1: Sequence[int], line2: Sequence[int]):
79    def intersect(self, line1: Sequence[int], line2: Sequence[int]):
80        """
81        Returns the intersection of the lines connecting the given indices.
82
83        Args:
84            line1 (Sequence[int]): A sequence containing two indices (ind1, ind2).
85            line2 (Sequence[int]): A sequence containing two indices (ind3, ind4).
86
87        Returns:
88            tuple: (x, y) intersection point of the lines.
89        """
90        ind1, ind2 = line1
91        ind3, ind4 = line2
92
93        line1 = (self.points[ind1], self.points[ind2])
94        line2 = (self.points[ind3], self.points[ind4])
95
96        return intersect(line1, line2)

Returns the intersection of the lines connecting the given indices.

Arguments:
  • line1 (Sequence[int]): A sequence containing two indices (ind1, ind2).
  • line2 (Sequence[int]): A sequence containing two indices (ind3, ind4).
Returns:

tuple: (x, y) intersection point of the lines.

def line(self, ind1: int, ind2: int) -> tuple:
 98    def line(self, ind1: int, ind2: int) -> tuple:
 99        """
100        Returns the line connecting the given indices.
101
102        Args:
103            ind1 (int): The first index.
104            ind2 (int): The second index.
105
106        Returns:
107            tuple: The line connecting the two points.
108        """
109        return (self.points[ind1], self.points[ind2])

Returns the line connecting the given indices.

Arguments:
  • ind1 (int): The first index.
  • ind2 (int): The second index.
Returns:

tuple: The line connecting the two points.

def radial_point(self, radius, index: int):
111    def radial_point(self, radius, index: int):
112        """
113        Returns the point on the line connecting the center of the grid to the given index.
114        radius is the distance from the center to the point.
115        The index is the index of the point in the grid.
116
117        Args:
118            radius (float): The radius.
119            index (int): The index of the point.
120
121        Returns:
122            tuple: The polar point.
123        """
124        return polar_to_cartesian(radius, index * (2 * pi / self.n))

Returns the point on the line connecting the center of the grid to the given index. radius is the distance from the center to the point. The index is the index of the point in the grid.

Arguments:
  • radius (float): The radius.
  • index (int): The index of the point.
Returns:

tuple: The polar point.

def between(self, ind1: int, ind2, t: float = 0.5) -> Sequence[float]:
126    def between(self, ind1: int, ind2, t: float = 0.5) -> Point:
127        """
128        Returns the point on the line connecting the given indices interpolated
129        by using the given t parameter.
130
131        Args:
132            ind1 (int): The first index.
133            ind2 (int): The second index.
134            t (float): The parameter used for interpolation. Default is 0.5.
135
136        Returns:
137            Point: The point on the line connecting the two points.
138        """
139        if t < 0 or t > 1:
140            raise ValueError("t must be between 0 and 1.")
141        if ind1 < 0 or ind1 >= len(self.points):
142            raise ValueError(f"ind1 must be between 0 and {len(self.points) - 1}.")
143        if ind1 == ind2:
144            raise ValueError("ind1 and ind2 must be different.")
145
146        return lerp_point(self.points[ind1], self.points[ind2], t)

Returns the point on the line connecting the given indices interpolated by using the given t parameter.

Arguments:
  • ind1 (int): The first index.
  • ind2 (int): The second index.
  • t (float): The parameter used for interpolation. Default is 0.5.
Returns:

Point: The point on the line connecting the two points.

class CircularGrid(Grid):
149class CircularGrid(Grid):
150    """A grid formed by connections of regular polygon points."""
151
152    def __init__(
153        self, center: Point = (0, 0), n: int = 12, radius: float = 100, n_circles=1
154    ):
155        """
156        Initializes the grid with the given center, radius, number of rows, and number of columns.
157
158        Args:
159            center (Point): The center point of the grid.
160            n (int): The number of points in the regular polygon.
161            radius (float): The radius of the grid.
162            n_circles (int): The number of circles in the grid. Used for drawing the grid.
163        """
164        points = reg_poly_points(center, n, radius)
165        super().__init__(GridType.CIRCULAR, center, n, radius, points, n_circles)
166
167        self.append(Circle(center, radius, fill=False))

A grid formed by connections of regular polygon points.

CircularGrid( center: Sequence[float] = (0, 0), n: int = 12, radius: float = 100, n_circles=1)
152    def __init__(
153        self, center: Point = (0, 0), n: int = 12, radius: float = 100, n_circles=1
154    ):
155        """
156        Initializes the grid with the given center, radius, number of rows, and number of columns.
157
158        Args:
159            center (Point): The center point of the grid.
160            n (int): The number of points in the regular polygon.
161            radius (float): The radius of the grid.
162            n_circles (int): The number of circles in the grid. Used for drawing the grid.
163        """
164        points = reg_poly_points(center, n, radius)
165        super().__init__(GridType.CIRCULAR, center, n, radius, points, n_circles)
166
167        self.append(Circle(center, radius, fill=False))

Initializes the grid with the given center, radius, number of rows, and number of columns.

Arguments:
  • center (Point): The center point of the grid.
  • n (int): The number of points in the regular polygon.
  • radius (float): The radius of the grid.
  • n_circles (int): The number of circles in the grid. Used for drawing the grid.
class HexGrid(Grid):
169class HexGrid(Grid):
170    """A grid formed by connections of regular polygon points."""
171
172    def __init__(self, center: Point = (0, 0), radius: float = 100, n_circles=1):
173        """
174        Initializes the grid with the given center, radius, number of rows, and number of columns.
175
176        Args:
177            center (Point): The center point of the hexagon.
178            radius (float): The circumradius of the hexagon.
179            n_circles (int): The number of circles in the grid. Used for drawing the grid.
180        """
181        points = reg_poly_points(center, 6, radius)
182        super().__init__(GridType.HEXAGONAL, center, 6, radius, points, n_circles)

A grid formed by connections of regular polygon points.

HexGrid(center: Sequence[float] = (0, 0), radius: float = 100, n_circles=1)
172    def __init__(self, center: Point = (0, 0), radius: float = 100, n_circles=1):
173        """
174        Initializes the grid with the given center, radius, number of rows, and number of columns.
175
176        Args:
177            center (Point): The center point of the hexagon.
178            radius (float): The circumradius of the hexagon.
179            n_circles (int): The number of circles in the grid. Used for drawing the grid.
180        """
181        points = reg_poly_points(center, 6, radius)
182        super().__init__(GridType.HEXAGONAL, center, 6, radius, points, n_circles)

Initializes the grid with the given center, radius, number of rows, and number of columns.

Arguments:
  • center (Point): The center point of the hexagon.
  • radius (float): The circumradius of the hexagon.
  • n_circles (int): The number of circles in the grid. Used for drawing the grid.
class SquareGrid(Grid):
185class SquareGrid(Grid):
186    """A grid formed by connections of square cells."""
187
188    def __init__(self, center: Point = (0, 0), n: int = 16, cell_size: float = 25):
189        """
190        Initializes the grid with the given center, number of rows, number of columns, and cell size.
191
192        Args:
193            center (Point): The center point of the grid.
194            n (int): The number of points in the grid. Square of an even integer.
195            cell_size (float): The size of each cell in the grid.
196        """
197        self.cell_size = cell_size
198        self.width = cell_size * n / 4
199        hs = int(sqrt(n) // 2)  # half size
200        c = cell_size
201        vals = [c * x for x in range(-hs, hs + 1)]
202        coords = list(product(vals, repeat=2))
203
204        def sort_key(coord):
205            r, _ = cartesian_to_polar(*coord)
206            return r
207
208        def sort_key2(coord):
209            _, theta = cartesian_to_polar(*coord)
210            return theta
211
212        coords.sort(key=sort_key, reverse=True)
213        coords = coords[:n]
214        coords.sort(key=sort_key2)
215        points = coords
216        radius = (2 * (cell_size * sqrt(n))**2)**.5
217        super().__init__(GridType.SQUARE, center, n, radius, points)

A grid formed by connections of square cells.

SquareGrid(center: Sequence[float] = (0, 0), n: int = 16, cell_size: float = 25)
188    def __init__(self, center: Point = (0, 0), n: int = 16, cell_size: float = 25):
189        """
190        Initializes the grid with the given center, number of rows, number of columns, and cell size.
191
192        Args:
193            center (Point): The center point of the grid.
194            n (int): The number of points in the grid. Square of an even integer.
195            cell_size (float): The size of each cell in the grid.
196        """
197        self.cell_size = cell_size
198        self.width = cell_size * n / 4
199        hs = int(sqrt(n) // 2)  # half size
200        c = cell_size
201        vals = [c * x for x in range(-hs, hs + 1)]
202        coords = list(product(vals, repeat=2))
203
204        def sort_key(coord):
205            r, _ = cartesian_to_polar(*coord)
206            return r
207
208        def sort_key2(coord):
209            _, theta = cartesian_to_polar(*coord)
210            return theta
211
212        coords.sort(key=sort_key, reverse=True)
213        coords = coords[:n]
214        coords.sort(key=sort_key2)
215        points = coords
216        radius = (2 * (cell_size * sqrt(n))**2)**.5
217        super().__init__(GridType.SQUARE, center, n, radius, points)

Initializes the grid with the given center, number of rows, number of columns, and cell size.

Arguments:
  • center (Point): The center point of the grid.
  • n (int): The number of points in the grid. Square of an even integer.
  • cell_size (float): The size of each cell in the grid.
cell_size
width
def convert_basis(x: float, y: float, basis: tuple):
222def convert_basis(x: float, y: float, basis: tuple):
223    """
224    Converts the given (x, y) coordinates from the standard basis to the given basis.
225
226    Args:
227        x (float): The x-coordinate.
228        y (float): The y-coordinate.
229        basis (tuple): The basis to convert to.
230
231    Returns:
232        tuple: The converted (x, y) coordinates.
233    """
234    return basis[0][0] * x + basis[0][1] * y, basis[1][0] * x + basis[1][1] * y

Converts the given (x, y) coordinates from the standard basis to the given basis.

Arguments:
  • x (float): The x-coordinate.
  • y (float): The y-coordinate.
  • basis (tuple): The basis to convert to.
Returns:

tuple: The converted (x, y) coordinates.

def convert_to_cartesian(x: float, y: float, basis: tuple):
237def convert_to_cartesian(x: float, y: float, basis: tuple):
238    """
239    Converts the given (x, y) coordinates from the given basis to the standard basis.
240
241    Args:
242        x (float): The x-coordinate.
243        y (float): The y-coordinate.
244        basis (tuple): The basis to convert from.
245
246    Returns:
247        tuple: The converted (x, y) coordinates.
248    """
249    return basis[0][0] * x + basis[1][0] * y, basis[0][1] * x + basis[1][1] * y

Converts the given (x, y) coordinates from the given basis to the standard basis.

Arguments:
  • x (float): The x-coordinate.
  • y (float): The y-coordinate.
  • basis (tuple): The basis to convert from.
Returns:

tuple: The converted (x, y) coordinates.

def cartesian_to_isometric(x: float, y: float):
252def cartesian_to_isometric(x: float, y: float):
253    """
254    Converts the given (x, y) coordinates to isometric coordinates.
255
256    Args:
257        x (float): The x-coordinate.
258        y (float): The y-coordinate.
259
260    Returns:
261        tuple: The isometric (x, y) coordinates.
262    """
263    return convert_basis(x, y, ((1, 0), (cos(pi / 3), sin(pi / 3))))

Converts the given (x, y) coordinates to isometric coordinates.

Arguments:
  • x (float): The x-coordinate.
  • y (float): The y-coordinate.
Returns:

tuple: The isometric (x, y) coordinates.

def isometric_to_cartesian(x: float, y: float):
266def isometric_to_cartesian(x: float, y: float):
267    """
268    Converts the given isometric (x, y) coordinates to Cartesian coordinates.
269
270    Args:
271        x (float): The x-coordinate.
272        y (float): The y-coordinate.
273
274    Returns:
275        tuple: The Cartesian (x, y) coordinates.
276    """
277    return convert_to_cartesian(x, y, ((1, 0), (cos(pi / 3), sin(pi / 3))))

Converts the given isometric (x, y) coordinates to Cartesian coordinates.

Arguments:
  • x (float): The x-coordinate.
  • y (float): The y-coordinate.
Returns:

tuple: The Cartesian (x, y) coordinates.