diff options
| author | Simon Tatham <anakin@pobox.com> | 2017-11-18 15:16:40 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 2017-11-18 15:26:13 +0000 |
| commit | 8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9 (patch) | |
| tree | 4dd554e21df0d6fff2d4a226c8df8a64c86e53ee /grid.c | |
| parent | 69773d855b517ea356c3c02add97893201de2066 (diff) | |
| download | puzzles-8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9.zip puzzles-8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9.tar.gz puzzles-8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9.tar.bz2 puzzles-8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9.tar.xz | |
New grid type: the trihexagonal tiling, or 'kagome lattice'.
Regular hexagons and equilateral triangles in strict alternation, with
two of each interleaved around each vertex.
https://en.wikipedia.org/wiki/Trihexagonal_tiling
Thanks to Michael Quevillon for the patch.
Diffstat (limited to 'grid.c')
| -rw-r--r-- | grid.c | 96 |
1 files changed, 96 insertions, 0 deletions
@@ -2060,6 +2060,102 @@ static grid *grid_new_greathexagonal(int width, int height, const char *desc) return g; } +#define KAGOME_TILESIZE 18 +/* Vector for side of triangle - ratio is close to sqrt(3) */ +#define KAGOME_A 15 +#define KAGOME_B 26 + +static void grid_size_kagome(int width, int height, + int *tilesize, int *xextent, int *yextent) +{ + int a = KAGOME_A; + int b = KAGOME_B; + + *tilesize = KAGOME_TILESIZE; + *xextent = (4*a) * (width-1) + 6*a; + *yextent = (2*b) * (height-1) + 2*b; +} + +static grid *grid_new_kagome(int width, int height, const char *desc) +{ + int x, y; + int a = KAGOME_A; + int b = KAGOME_B; + + /* Upper bounds - don't have to be exact */ + int max_faces = 6 * (width + 1) * (height + 1); + int max_dots = 6 * width * height; + + tree234 *points; + + grid *g = grid_empty(); + g->tilesize = KAGOME_TILESIZE; + g->faces = snewn(max_faces, grid_face); + g->dots = snewn(max_dots, grid_dot); + + points = newtree234(grid_point_cmp_fn); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + grid_dot *d; + /* centre of hexagon */ + int px = (4*a) * x; + int py = (2*b) * y; + if (y % 2) + px += 2*a; + + /* hexagon */ + grid_face_add_new(g, 6); + d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 0); + d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1); + d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 2); + d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 3); + d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 4); + d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 5); + + /* Triangle above right */ + if ((x < width - 1) || (!(y % 2) && y)) { + grid_face_add_new(g, 3); + d = grid_get_dot(g, points, px + 3*a, py - b); grid_face_set_dot(g, d, 0); + d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 1); + d = grid_get_dot(g, points, px + a, py - b); grid_face_set_dot(g, d, 2); + } + + /* Triangle below right */ + if ((x < width - 1) || (!(y % 2) && (y < height - 1))) { + grid_face_add_new(g, 3); + d = grid_get_dot(g, points, px + 3*a, py + b); grid_face_set_dot(g, d, 0); + d = grid_get_dot(g, points, px + a, py + b); grid_face_set_dot(g, d, 1); + d = grid_get_dot(g, points, px + 2*a, py ); grid_face_set_dot(g, d, 2); + } + + /* Left triangles */ + if (!x && (y % 2)) { + /* Triangle above left */ + grid_face_add_new(g, 3); + d = grid_get_dot(g, points, px - a, py - b); grid_face_set_dot(g, d, 0); + d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 1); + d = grid_get_dot(g, points, px - 3*a, py - b); grid_face_set_dot(g, d, 2); + + /* Triangle below left */ + if (y < height - 1) { + grid_face_add_new(g, 3); + d = grid_get_dot(g, points, px - a, py + b); grid_face_set_dot(g, d, 0); + d = grid_get_dot(g, points, px - 3*a, py + b); grid_face_set_dot(g, d, 1); + d = grid_get_dot(g, points, px - 2*a, py ); grid_face_set_dot(g, d, 2); + } + } + } + } + + freetree234(points); + assert(g->num_faces <= max_faces); + assert(g->num_dots <= max_dots); + + grid_make_consistent(g); + return g; +} + #define OCTAGONAL_TILESIZE 40 /* b/a approx sqrt(2) */ #define OCTAGONAL_A 29 |