aboutsummaryrefslogtreecommitdiff
path: root/grid.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2017-11-18 15:16:40 +0000
committerSimon Tatham <anakin@pobox.com>2017-11-18 15:26:13 +0000
commit8af0c29615fdfe30035f2d4c3a7d2ccf06d6efa9 (patch)
tree4dd554e21df0d6fff2d4a226c8df8a64c86e53ee /grid.c
parent69773d855b517ea356c3c02add97893201de2066 (diff)
downloadpuzzles-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.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/grid.c b/grid.c
index 52648e5..b5e6bb0 100644
--- a/grid.c
+++ b/grid.c
@@ -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