hexsample.hexagon — Hexagonal sampling#

The module is an attempt at having a fully-fledged version of all the necessary facilities related to the geometry on an hexagonal grid all in the same place, most of the information coming from https://www.redblobgames.com/grids/hexagons/.

As a very quick, top level recap, hexagonal grids are classified according to their orientation as either pointy-top (with staggered rows, in a vertical layout) or flat-top (with staggered columns, in a horizontal layout). Each layout comes into versions, depending on whether even or odd rows/columns are shoved right/down. We end up with the four basic arrangements shown in the figure below, all of which are supported.

_images/hexagonal_layouts.png

The module provides a HexagonalGrid class, representing an hexagonal grid, whose main public interfaces, pixel_to_world(col, row) and world_to_pixel(x, y), allow to go back and forth from logical to physical coordinates and vice versa. It is worth pointing out that, in all four cases, the origin of the physical reference system is assumed to be at the center of the grid, as illustrated in the image.

Module documentation#

Geometrical facilities on a hexagonal grid.

class hexsample.hexagon.HexagonalLayout(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)#

Enum class expressing the possible grid layouts.

ODD_R = 'ODD_R'#
EVEN_R = 'EVEN_R'#
ODD_Q = 'ODD_Q'#
EVEN_Q = 'EVEN_Q'#
hexsample.hexagon.neighbors_odd_r(col: int, row: int) tuple#

Return a tuple with the coordinates of the 6 neighbor pixel for a given pixel in a ODD_R hexagonal grid.

Parameters:
  • col (int) – The column index.

  • row (int) – The row index.

hexsample.hexagon.neighbors_even_r(col: int, row: int) tuple#

Return a tuple with the coordinates of the 6 neighbor pixel for a given pixel in a EVEN_R hexagonal grid.

Parameters:
  • col (int) – The column index.

  • row (int) – The row index.

hexsample.hexagon.neighbors_odd_q(col: int, row: int) tuple#

Return a tuple with the coordinates of the 6 neighbor pixel for a given pixel in a ODD_Q hexagonal grid.

Parameters:
  • col (int) – The column index.

  • row (int) – The row index.

hexsample.hexagon.neighbors_even_q(col: int, row: int) tuple#

Return a tuple with the coordinates of the 6 neighbor pixel for a given pixel in a EVEN_Q hexagonal grid.

Parameters:
  • col (int) – The column index.

  • row (int) – The row index.

hexsample.hexagon.adc_channel_odd_r(col: int, row: int) int#

Transformation from offset coordinates (col, row) into 7-adc channel label, that is an int between 0 and 6, for ODD_R grid layout.

Parameters:
  • col (int) – column pixel logical coordinate

  • row (int) – row pixel logical coordinate

hexsample.hexagon.adc_channel_even_r(col: int, row: int) int#

Transformation from offset coordinates (col, row) into 7-adc channel label, that is an int between 0 and 6, for EVEN_R grid layout.

Parameters:
  • col (int) – column pixel logical coordinate

  • row (int) – row pixel logical coordinate

hexsample.hexagon.adc_channel_odd_q(col: int, row: int) int#

Transformation from offset coordinates (col, row) into 7-adc channel label, that is an int between 0 and 6, for ODD_Q grid layout.

Parameters:
  • col (int) – column pixel logical coordinate

  • row (int) – row pixel logical coordinate

hexsample.hexagon.adc_channel_even_q(col: int, row: int) int#

Transformation from offset coordinates (col, row) into 7-adc channel label, that is an int between 0 and 6, for EVEN_Q grid layout.

Parameters:
  • col (int) – column pixel logical coordinate

  • row (int) – row pixel logical coordinate

class hexsample.hexagon.HexagonalGrid(layout: HexagonalLayout, num_cols: int, num_rows: int, pitch: float)#

Generic hexagonal grid, with the origin of the physical coordinate system at its center.

Parameters:
  • layout (HexagonalLayout) – The underlying hexagonal grid layout.

  • num_cols (int) – The number of columns in the grid

  • num_rows (int) – The number of rows in the grid

  • pitch (float) – The grid pitch in mm.

pointy_topped() bool#

Return True if the layout is pointy-topped.

flat_topped() bool#

Return True if the layout is flat-topped.

even() bool#

Return True if the layout is even.

odd() bool#

Return True if the layout is odd.

hexagon_orientation() float#

Return the orientation (rotation angle in radians) of the grid hexagons.

This is calculated according to the matplotlib conventions for a RegularPolygon, that is, it’s 0 for a pointy top, and pi/2 for a flat top.

_parity_offset(index: int) int#

Small convenience function to help with the tranformation.

For any given column or row index, this returns 0 if the index is even and +1 or - 1 (depending on whether the parent layout is even or odd) if the index is odd.

Parameters:

index (int) – The column or row index.

pixel_to_world(col: array, row: array) Tuple[array, array]#

Transform pixel coordinates to world coordinates.

Parameters:
  • col (array_like) – The input column number(s).

  • row (array_like) – The input row number(s).

_float_axial(x: array, y: array) Tuple[array, array]#

Conversion of a given set of world coordinates into fractional axial coordinates, a. k. a. step 1 in the transformation between world coordinates to pixel coordinates.

See https://www.redblobgames.com/grids/hexagons/ for more details.

Parameters:
  • x (array_like) – The x coordinate(s).

  • y (array_like) – The y coordinate(s).

static _axial_round(q: array, r: array) Tuple[array, array]#

Rounding to integer of the axial coordinates, a. k. a. step 2 in the transformation between world coordinates to pixel coordinates.

See https://www.redblobgames.com/grids/hexagons/ for more details.

Parameters:
  • q (array_like) – The q axial coordinate(s).

  • r (array_like) – The r axial coordinate(s).

_axial_to_offset(q: array, r: array) Tuple[array, array]#

Conversion from axial to offset coordinates, a. k. a. step 3 in the transformation between world coordinates to pixel coordinates.

See https://www.redblobgames.com/grids/hexagons/ for more details.

Parameters:
  • q (array_like) – The q axial coordinate(s).

  • r (array_like) – The r axial coordinate(s).

world_to_pixel(x: array, y: array) Tuple[array, array]#

Transform world coordinates to pixel coordinates.

This proceeds in three basic steps (conversion to fractional axial coordinates, rounding to integer and conversion to offset coordinates) as described in https://www.redblobgames.com/grids/hexagons/ and we factored the three steps into three separate functions to clarify the code flow.

Parameters:
  • x (array_like) – The input x coordinate(s).

  • y (array_like) – The input y coordinate(s).

pixel_logical_coordinates() Tuple[array, array]#

Return a 2-element tuple (cols, rows) of numpy arrays containing all the column and row indices that allow to loop over the full matrix. The specific order in which the pixels are looped upon is completely arbitrary and, for the sake of this function, we assume that, e.g., for a 2 x 2 grid we return >>> cols = [0, 1, 0, 1] >>> rows = [0, 0, 1, 1] i.e., we loop with the following order >>> (0, 0), (1, 0), (0, 1), (1, 1)

pixel_physical_coordinates() Tuple[array, array, array, array]#

Return a 4-element tuple (cols, rows, x, y) containing the logical coordinates returned by pixel_logical_coordinates(), along with the corresponding physical coordinates.