- /* generate faces */
- index = 0;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- /* initialise two faces for this (x,y) */
- grid_face *f1 = g->faces + index;
- grid_face *f2 = f1 + 1;
- f1->edges = NULL;
- f1->order = 3;
- f1->dots = snewn(f1->order, grid_dot*);
- f1->has_incentre = FALSE;
- f2->edges = NULL;
- f2->order = 3;
- f2->dots = snewn(f2->order, grid_dot*);
- f2->has_incentre = FALSE;
-
- /* face descriptions depend on whether the row-number is
- * odd or even */
+ /* generate faces */
+ index = 0;
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ /* initialise two faces for this (x,y) */
+ grid_face *f1 = g->faces + index;
+ grid_face *f2 = f1 + 1;
+ f1->edges = NULL;
+ f1->order = 3;
+ f1->dots = snewn(f1->order, grid_dot*);
+ f1->has_incentre = FALSE;
+ f2->edges = NULL;
+ f2->order = 3;
+ f2->dots = snewn(f2->order, grid_dot*);
+ f2->has_incentre = FALSE;
+
+ /* face descriptions depend on whether the row-number is
+ * odd or even */
+ if (y % 2) {
+ f1->dots[0] = g->dots + y * w + x;
+ f1->dots[1] = g->dots + (y + 1) * w + x + 1;
+ f1->dots[2] = g->dots + (y + 1) * w + x;
+ f2->dots[0] = g->dots + y * w + x;
+ f2->dots[1] = g->dots + y * w + x + 1;
+ f2->dots[2] = g->dots + (y + 1) * w + x + 1;
+ } else {
+ f1->dots[0] = g->dots + y * w + x;
+ f1->dots[1] = g->dots + y * w + x + 1;
+ f1->dots[2] = g->dots + (y + 1) * w + x;
+ f2->dots[0] = g->dots + y * w + x + 1;
+ f2->dots[1] = g->dots + (y + 1) * w + x + 1;
+ f2->dots[2] = g->dots + (y + 1) * w + x;
+ }
+ index += 2;
+ }
+ }
+ } else {
+ /*
+ * New-style approach, in which there are never any 'ears',
+ * and if height is even then the grid is nicely 4-way
+ * symmetric.
+ *
+ * Example new-style grids:
+ *
+ * 5x5t1:0_21120b11a1a01a1a00c1a0b211021c1h1a2a1a0a
+ * 5x6t1:0_a1212c22c2a02a2f22a0c12a110d0e1c0c0a101121a1
+ */
+ tree234 *points = newtree234(grid_point_cmp_fn);
+ /* Upper bounds - don't have to be exact */
+ int max_faces = height * (2*width+1);
+ int max_dots = (height+1) * (width+1) * 4;
+
+ g->faces = snewn(max_faces, grid_face);
+ g->dots = snewn(max_dots, grid_dot);
+
+ for (y = 0; y < height; y++) {
+ /*
+ * Each row contains (width+1) triangles one way up, and
+ * (width) triangles the other way up. Which way up is
+ * which varies with parity of y. Also, the dots around
+ * each face will flip direction with parity of y, so we
+ * set up n1 and n2 to cope with that easily.
+ */
+ int y0, y1, n1, n2;
+ y0 = y1 = y * vec_y;