chiark / gitweb /
Forgot to set 'has_incentre' on triangular grids, which don't use
[sgt-puzzles.git] / grid.c
1 /*
2  * (c) Lambros Lambrou 2008
3  *
4  * Code for working with general grids, which can be any planar graph
5  * with faces, edges and vertices (dots).  Includes generators for a few
6  * types of grid, including square, hexagonal, triangular and others.
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <assert.h>
13 #include <ctype.h>
14 #include <math.h>
15 #include <errno.h>
16
17 #include "puzzles.h"
18 #include "tree234.h"
19 #include "grid.h"
20 #include "penrose.h"
21
22 /* Debugging options */
23
24 /*
25 #define DEBUG_GRID
26 */
27
28 /* ----------------------------------------------------------------------
29  * Deallocate or dereference a grid
30  */
31 void grid_free(grid *g)
32 {
33     assert(g->refcount);
34
35     g->refcount--;
36     if (g->refcount == 0) {
37         int i;
38         for (i = 0; i < g->num_faces; i++) {
39             sfree(g->faces[i].dots);
40             sfree(g->faces[i].edges);
41         }
42         for (i = 0; i < g->num_dots; i++) {
43             sfree(g->dots[i].faces);
44             sfree(g->dots[i].edges);
45         }
46         sfree(g->faces);
47         sfree(g->edges);
48         sfree(g->dots);
49         sfree(g);
50     }
51 }
52
53 /* Used by the other grid generators.  Create a brand new grid with nothing
54  * initialised (all lists are NULL) */
55 static grid *grid_empty()
56 {
57     grid *g = snew(grid);
58     g->faces = NULL;
59     g->edges = NULL;
60     g->dots = NULL;
61     g->num_faces = g->num_edges = g->num_dots = 0;
62     g->refcount = 1;
63     g->lowest_x = g->lowest_y = g->highest_x = g->highest_y = 0;
64     return g;
65 }
66
67 /* Helper function to calculate perpendicular distance from
68  * a point P to a line AB.  A and B mustn't be equal here.
69  *
70  * Well-known formula for area A of a triangle:
71  *                             /  1   1   1 \
72  * 2A = determinant of matrix  | px  ax  bx |
73  *                             \ py  ay  by /
74  *
75  * Also well-known: 2A = base * height
76  *                     = perpendicular distance * line-length.
77  *
78  * Combining gives: distance = determinant / line-length(a,b)
79  */
80 static double point_line_distance(long px, long py,
81                                   long ax, long ay,
82                                   long bx, long by)
83 {
84     long det = ax*by - bx*ay + bx*py - px*by + px*ay - ax*py;
85     double len;
86     det = max(det, -det);
87     len = sqrt(SQ(ax - bx) + SQ(ay - by));
88     return det / len;
89 }
90
91 /* Determine nearest edge to where the user clicked.
92  * (x, y) is the clicked location, converted to grid coordinates.
93  * Returns the nearest edge, or NULL if no edge is reasonably
94  * near the position.
95  *
96  * Just judging edges by perpendicular distance is not quite right -
97  * the edge might be "off to one side". So we insist that the triangle
98  * with (x,y) has acute angles at the edge's dots.
99  *
100  *     edge1
101  *  *---------*------
102  *            |
103  *            |      *(x,y)
104  *      edge2 |
105  *            |   edge2 is OK, but edge1 is not, even though
106  *            |   edge1 is perpendicularly closer to (x,y)
107  *            *
108  *
109  */
110 grid_edge *grid_nearest_edge(grid *g, int x, int y)
111 {
112     grid_edge *best_edge;
113     double best_distance = 0;
114     int i;
115
116     best_edge = NULL;
117
118     for (i = 0; i < g->num_edges; i++) {
119         grid_edge *e = &g->edges[i];
120         long e2; /* squared length of edge */
121         long a2, b2; /* squared lengths of other sides */
122         double dist;
123
124         /* See if edge e is eligible - the triangle must have acute angles
125          * at the edge's dots.
126          * Pythagoras formula h^2 = a^2 + b^2 detects right-angles,
127          * so detect acute angles by testing for h^2 < a^2 + b^2 */
128         e2 = SQ((long)e->dot1->x - (long)e->dot2->x) + SQ((long)e->dot1->y - (long)e->dot2->y);
129         a2 = SQ((long)e->dot1->x - (long)x) + SQ((long)e->dot1->y - (long)y);
130         b2 = SQ((long)e->dot2->x - (long)x) + SQ((long)e->dot2->y - (long)y);
131         if (a2 >= e2 + b2) continue;
132         if (b2 >= e2 + a2) continue;
133          
134         /* e is eligible so far.  Now check the edge is reasonably close
135          * to where the user clicked.  Don't want to toggle an edge if the
136          * click was way off the grid.
137          * There is room for experimentation here.  We could check the
138          * perpendicular distance is within a certain fraction of the length
139          * of the edge.  That amounts to testing a rectangular region around
140          * the edge.
141          * Alternatively, we could check that the angle at the point is obtuse.
142          * That would amount to testing a circular region with the edge as
143          * diameter. */
144         dist = point_line_distance((long)x, (long)y,
145                                    (long)e->dot1->x, (long)e->dot1->y,
146                                    (long)e->dot2->x, (long)e->dot2->y);
147         /* Is dist more than half edge length ? */
148         if (4 * SQ(dist) > e2)
149             continue;
150
151         if (best_edge == NULL || dist < best_distance) {
152             best_edge = e;
153             best_distance = dist;
154         }
155     }
156     return best_edge;
157 }
158
159 /* ----------------------------------------------------------------------
160  * Grid generation
161  */
162
163 #ifdef SVG_GRID
164
165 #define SVG_DOTS  1
166 #define SVG_EDGES 2
167 #define SVG_FACES 4
168
169 #define FACE_COLOUR "red"
170 #define EDGE_COLOUR "blue"
171 #define DOT_COLOUR "black"
172
173 static void grid_output_svg(FILE *fp, grid *g, int which)
174 {
175     int i, j;
176
177     fprintf(fp,"\
178 <?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n\
179 <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\"\n\
180 \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\
181 \n\
182 <svg xmlns=\"http://www.w3.org/2000/svg\"\n\
183 xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\n");
184
185     if (which & SVG_FACES) {
186         fprintf(fp, "<g>\n");
187         for (i = 0; i < g->num_faces; i++) {
188             grid_face *f = g->faces + i;
189             fprintf(fp, "<polygon points=\"");
190             for (j = 0; j < f->order; j++) {
191                 grid_dot *d = f->dots[j];
192                 fprintf(fp, "%s%d,%d", (j == 0) ? "" : " ",
193                         d->x, d->y);
194             }
195             fprintf(fp, "\" style=\"fill: %s; fill-opacity: 0.2; stroke: %s\" />\n",
196                     FACE_COLOUR, FACE_COLOUR);
197         }
198         fprintf(fp, "</g>\n");
199     }
200     if (which & SVG_EDGES) {
201         fprintf(fp, "<g>\n");
202         for (i = 0; i < g->num_edges; i++) {
203             grid_edge *e = g->edges + i;
204             grid_dot *d1 = e->dot1, *d2 = e->dot2;
205
206             fprintf(fp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" "
207                         "style=\"stroke: %s\" />\n",
208                         d1->x, d1->y, d2->x, d2->y, EDGE_COLOUR);
209         }
210         fprintf(fp, "</g>\n");
211     }
212
213     if (which & SVG_DOTS) {
214         fprintf(fp, "<g>\n");
215         for (i = 0; i < g->num_dots; i++) {
216             grid_dot *d = g->dots + i;
217             fprintf(fp, "<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" fill=\"%s\" />",
218                     d->x, d->y, g->tilesize/20, g->tilesize/20, DOT_COLOUR);
219         }
220         fprintf(fp, "</g>\n");
221     }
222
223     fprintf(fp, "</svg>\n");
224 }
225 #endif
226
227 #ifdef SVG_GRID
228 static void grid_try_svg(grid *g, int which)
229 {
230     char *svg = getenv("PUZZLES_SVG_GRID");
231     if (svg) {
232         FILE *svgf = fopen(svg, "w");
233         if (svgf) {
234             grid_output_svg(svgf, g, which);
235             fclose(svgf);
236         } else {
237             fprintf(stderr, "Unable to open file `%s': %s", svg, strerror(errno));
238         }
239     }
240 }
241 #endif
242
243 /* Show the basic grid information, before doing grid_make_consistent */
244 static void grid_debug_basic(grid *g)
245 {
246     /* TODO: Maybe we should generate an SVG image of the dots and lines
247      * of the grid here, before grid_make_consistent.
248      * Would help with debugging grid generation. */
249 #ifdef DEBUG_GRID
250     int i;
251     printf("--- Basic Grid Data ---\n");
252     for (i = 0; i < g->num_faces; i++) {
253         grid_face *f = g->faces + i;
254         printf("Face %d: dots[", i);
255         int j;
256         for (j = 0; j < f->order; j++) {
257             grid_dot *d = f->dots[j];
258             printf("%s%d", j ? "," : "", (int)(d - g->dots)); 
259         }
260         printf("]\n");
261     }
262 #endif
263 #ifdef SVG_GRID
264     grid_try_svg(g, SVG_FACES);
265 #endif
266 }
267
268 /* Show the derived grid information, computed by grid_make_consistent */
269 static void grid_debug_derived(grid *g)
270 {
271 #ifdef DEBUG_GRID
272     /* edges */
273     int i;
274     printf("--- Derived Grid Data ---\n");
275     for (i = 0; i < g->num_edges; i++) {
276         grid_edge *e = g->edges + i;
277         printf("Edge %d: dots[%d,%d] faces[%d,%d]\n",
278             i, (int)(e->dot1 - g->dots), (int)(e->dot2 - g->dots),
279             e->face1 ? (int)(e->face1 - g->faces) : -1,
280             e->face2 ? (int)(e->face2 - g->faces) : -1);
281     }
282     /* faces */
283     for (i = 0; i < g->num_faces; i++) {
284         grid_face *f = g->faces + i;
285         int j;
286         printf("Face %d: faces[", i);
287         for (j = 0; j < f->order; j++) {
288             grid_edge *e = f->edges[j];
289             grid_face *f2 = (e->face1 == f) ? e->face2 : e->face1;
290             printf("%s%d", j ? "," : "", f2 ? (int)(f2 - g->faces) : -1);
291         }
292         printf("]\n");
293     }
294     /* dots */
295     for (i = 0; i < g->num_dots; i++) {
296         grid_dot *d = g->dots + i;
297         int j;
298         printf("Dot %d: dots[", i);
299         for (j = 0; j < d->order; j++) {
300             grid_edge *e = d->edges[j];
301             grid_dot *d2 = (e->dot1 == d) ? e->dot2 : e->dot1;
302             printf("%s%d", j ? "," : "", (int)(d2 - g->dots));
303         }
304         printf("] faces[");
305         for (j = 0; j < d->order; j++) {
306             grid_face *f = d->faces[j];
307             printf("%s%d", j ? "," : "", f ? (int)(f - g->faces) : -1);
308         }
309         printf("]\n");
310     }
311 #endif
312 #ifdef SVG_GRID
313     grid_try_svg(g, SVG_DOTS | SVG_EDGES | SVG_FACES);
314 #endif
315 }
316
317 /* Helper function for building incomplete-edges list in
318  * grid_make_consistent() */
319 static int grid_edge_bydots_cmpfn(void *v1, void *v2)
320 {
321     grid_edge *a = v1;
322     grid_edge *b = v2;
323     grid_dot *da, *db;
324
325     /* Pointer subtraction is valid here, because all dots point into the
326      * same dot-list (g->dots).
327      * Edges are not "normalised" - the 2 dots could be stored in any order,
328      * so we need to take this into account when comparing edges. */
329
330     /* Compare first dots */
331     da = (a->dot1 < a->dot2) ? a->dot1 : a->dot2;
332     db = (b->dot1 < b->dot2) ? b->dot1 : b->dot2;
333     if (da != db)
334         return db - da;
335     /* Compare last dots */
336     da = (a->dot1 < a->dot2) ? a->dot2 : a->dot1;
337     db = (b->dot1 < b->dot2) ? b->dot2 : b->dot1;
338     if (da != db)
339         return db - da;
340
341     return 0;
342 }
343
344 /*
345  * 'Vigorously trim' a grid, by which I mean deleting any isolated or
346  * uninteresting faces. By which, in turn, I mean: ensure that the
347  * grid is composed solely of faces adjacent to at least one
348  * 'landlocked' dot (i.e. one not in contact with the infinite
349  * exterior face), and that all those dots are in a single connected
350  * component.
351  *
352  * This function operates on, and returns, a grid satisfying the
353  * preconditions to grid_make_consistent() rather than the
354  * postconditions. (So call it first.)
355  */
356 static void grid_trim_vigorously(grid *g)
357 {
358     int *dotpairs, *faces, *dots;
359     int *dsf;
360     int i, j, k, size, newfaces, newdots;
361
362     /*
363      * First construct a matrix in which each ordered pair of dots is
364      * mapped to the index of the face in which those dots occur in
365      * that order.
366      */
367     dotpairs = snewn(g->num_dots * g->num_dots, int);
368     for (i = 0; i < g->num_dots; i++)
369         for (j = 0; j < g->num_dots; j++)
370             dotpairs[i*g->num_dots+j] = -1;
371     for (i = 0; i < g->num_faces; i++) {
372         grid_face *f = g->faces + i;
373         int dot0 = f->dots[f->order-1] - g->dots;
374         for (j = 0; j < f->order; j++) {
375             int dot1 = f->dots[j] - g->dots;
376             dotpairs[dot0 * g->num_dots + dot1] = i;
377             dot0 = dot1;
378         }
379     }
380
381     /*
382      * Now we can identify landlocked dots: they're the ones all of
383      * whose edges have a mirror-image counterpart in this matrix.
384      */
385     dots = snewn(g->num_dots, int);
386     for (i = 0; i < g->num_dots; i++) {
387         dots[i] = TRUE;
388         for (j = 0; j < g->num_dots; j++) {
389             if ((dotpairs[i*g->num_dots+j] >= 0) ^
390                 (dotpairs[j*g->num_dots+i] >= 0))
391                 dots[i] = FALSE;    /* non-duplicated edge: coastal dot */
392         }
393     }
394
395     /*
396      * Now identify connected pairs of landlocked dots, and form a dsf
397      * unifying them.
398      */
399     dsf = snew_dsf(g->num_dots);
400     for (i = 0; i < g->num_dots; i++)
401         for (j = 0; j < i; j++)
402             if (dots[i] && dots[j] &&
403                 dotpairs[i*g->num_dots+j] >= 0 &&
404                 dotpairs[j*g->num_dots+i] >= 0)
405                 dsf_merge(dsf, i, j);
406
407     /*
408      * Now look for the largest component.
409      */
410     size = 0;
411     j = -1;
412     for (i = 0; i < g->num_dots; i++) {
413         int newsize;
414         if (dots[i] && dsf_canonify(dsf, i) == i &&
415             (newsize = dsf_size(dsf, i)) > size) {
416             j = i;
417             size = newsize;
418         }
419     }
420
421     /*
422      * Work out which faces we're going to keep (precisely those with
423      * at least one dot in the same connected component as j) and
424      * which dots (those required by any face we're keeping).
425      *
426      * At this point we reuse the 'dots' array to indicate the dots
427      * we're keeping, rather than the ones that are landlocked.
428      */
429     faces = snewn(g->num_faces, int);
430     for (i = 0; i < g->num_faces; i++)
431         faces[i] = 0;
432     for (i = 0; i < g->num_dots; i++)
433         dots[i] = 0;
434     for (i = 0; i < g->num_faces; i++) {
435         grid_face *f = g->faces + i;
436         int keep = FALSE;
437         for (k = 0; k < f->order; k++)
438             if (dsf_canonify(dsf, f->dots[k] - g->dots) == j)
439                 keep = TRUE;
440         if (keep) {
441             faces[i] = TRUE;
442             for (k = 0; k < f->order; k++)
443                 dots[f->dots[k]-g->dots] = TRUE;
444         }
445     }
446
447     /*
448      * Work out the new indices of those faces and dots, when we
449      * compact the arrays containing them.
450      */
451     for (i = newfaces = 0; i < g->num_faces; i++)
452         faces[i] = (faces[i] ? newfaces++ : -1);
453     for (i = newdots = 0; i < g->num_dots; i++)
454         dots[i] = (dots[i] ? newdots++ : -1);
455
456     /*
457      * Go through and compact the arrays.
458      */
459     for (i = 0; i < g->num_dots; i++)
460         if (dots[i] >= 0) {
461             grid_dot *dnew = g->dots + dots[i], *dold = g->dots + i;
462             *dnew = *dold;             /* structure copy */
463         }
464     for (i = 0; i < g->num_faces; i++)
465         if (faces[i] >= 0) {
466             grid_face *fnew = g->faces + faces[i], *fold = g->faces + i;
467             *fnew = *fold;             /* structure copy */
468             for (j = 0; j < fnew->order; j++) {
469                 /*
470                  * Reindex the dots in this face.
471                  */
472                 k = fnew->dots[j] - g->dots;
473                 fnew->dots[j] = g->dots + dots[k];
474             }
475         }
476     g->num_faces = newfaces;
477     g->num_dots = newdots;
478
479     sfree(dotpairs);
480     sfree(dsf);
481     sfree(dots);
482     sfree(faces);
483 }
484
485 /* Input: grid has its dots and faces initialised:
486  * - dots have (optionally) x and y coordinates, but no edges or faces
487  * (pointers are NULL).
488  * - edges not initialised at all
489  * - faces initialised and know which dots they have (but no edges yet).  The
490  * dots around each face are assumed to be clockwise.
491  *
492  * Output: grid is complete and valid with all relationships defined.
493  */
494 static void grid_make_consistent(grid *g)
495 {
496     int i;
497     tree234 *incomplete_edges;
498     grid_edge *next_new_edge; /* Where new edge will go into g->edges */
499
500     grid_debug_basic(g);
501
502     /* ====== Stage 1 ======
503      * Generate edges
504      */
505
506     /* We know how many dots and faces there are, so we can find the exact
507      * number of edges from Euler's polyhedral formula: F + V = E + 2 .
508      * We use "-1", not "-2" here, because Euler's formula includes the
509      * infinite face, which we don't count. */
510     g->num_edges = g->num_faces + g->num_dots - 1;
511     g->edges = snewn(g->num_edges, grid_edge);
512     next_new_edge = g->edges;
513
514     /* Iterate over faces, and over each face's dots, generating edges as we
515      * go.  As we find each new edge, we can immediately fill in the edge's
516      * dots, but only one of the edge's faces.  Later on in the iteration, we
517      * will find the same edge again (unless it's on the border), but we will
518      * know the other face.
519      * For efficiency, maintain a list of the incomplete edges, sorted by
520      * their dots. */
521     incomplete_edges = newtree234(grid_edge_bydots_cmpfn);
522     for (i = 0; i < g->num_faces; i++) {
523         grid_face *f = g->faces + i;
524         int j;
525         for (j = 0; j < f->order; j++) {
526             grid_edge e; /* fake edge for searching */
527             grid_edge *edge_found;
528             int j2 = j + 1;
529             if (j2 == f->order)
530                 j2 = 0;
531             e.dot1 = f->dots[j];
532             e.dot2 = f->dots[j2];
533             /* Use del234 instead of find234, because we always want to
534              * remove the edge if found */
535             edge_found = del234(incomplete_edges, &e);
536             if (edge_found) {
537                 /* This edge already added, so fill out missing face.
538                  * Edge is already removed from incomplete_edges. */
539                 edge_found->face2 = f;
540             } else {
541                 assert(next_new_edge - g->edges < g->num_edges);
542                 next_new_edge->dot1 = e.dot1;
543                 next_new_edge->dot2 = e.dot2;
544                 next_new_edge->face1 = f;
545                 next_new_edge->face2 = NULL; /* potentially infinite face */
546                 add234(incomplete_edges, next_new_edge);
547                 ++next_new_edge;
548             }
549         }
550     }
551     freetree234(incomplete_edges);
552     
553     /* ====== Stage 2 ======
554      * For each face, build its edge list.
555      */
556
557     /* Allocate space for each edge list.  Can do this, because each face's
558      * edge-list is the same size as its dot-list. */
559     for (i = 0; i < g->num_faces; i++) {
560         grid_face *f = g->faces + i;
561         int j;
562         f->edges = snewn(f->order, grid_edge*);
563         /* Preload with NULLs, to help detect potential bugs. */
564         for (j = 0; j < f->order; j++)
565             f->edges[j] = NULL;
566     }
567     
568     /* Iterate over each edge, and over both its faces.  Add this edge to
569      * the face's edge-list, after finding where it should go in the
570      * sequence. */
571     for (i = 0; i < g->num_edges; i++) {
572         grid_edge *e = g->edges + i;
573         int j;
574         for (j = 0; j < 2; j++) {
575             grid_face *f = j ? e->face2 : e->face1;
576             int k, k2;
577             if (f == NULL) continue;
578             /* Find one of the dots around the face */
579             for (k = 0; k < f->order; k++) {
580                 if (f->dots[k] == e->dot1)
581                     break; /* found dot1 */
582             }
583             assert(k != f->order); /* Must find the dot around this face */
584
585             /* Labelling scheme: as we walk clockwise around the face,
586              * starting at dot0 (f->dots[0]), we hit:
587              * (dot0), edge0, dot1, edge1, dot2,...
588              *
589              *     0
590              *  0-----1
591              *        |
592              *        |1
593              *        |
594              *  3-----2
595              *     2
596              *
597              * Therefore, edgeK joins dotK and dot{K+1}
598              */
599             
600             /* Around this face, either the next dot or the previous dot
601              * must be e->dot2.  Otherwise the edge is wrong. */
602             k2 = k + 1;
603             if (k2 == f->order)
604                 k2 = 0;
605             if (f->dots[k2] == e->dot2) {
606                 /* dot1(k) and dot2(k2) go clockwise around this face, so add
607                  * this edge at position k (see diagram). */
608                 assert(f->edges[k] == NULL);
609                 f->edges[k] = e;
610                 continue;
611             }
612             /* Try previous dot */
613             k2 = k - 1;
614             if (k2 == -1)
615                 k2 = f->order - 1;
616             if (f->dots[k2] == e->dot2) {
617                 /* dot1(k) and dot2(k2) go anticlockwise around this face. */
618                 assert(f->edges[k2] == NULL);
619                 f->edges[k2] = e;
620                 continue;
621             }
622             assert(!"Grid broken: bad edge-face relationship");
623         }
624     }
625
626     /* ====== Stage 3 ======
627      * For each dot, build its edge-list and face-list.
628      */
629
630     /* We don't know how many edges/faces go around each dot, so we can't
631      * allocate the right space for these lists.  Pre-compute the sizes by
632      * iterating over each edge and recording a tally against each dot. */
633     for (i = 0; i < g->num_dots; i++) {
634         g->dots[i].order = 0;
635     }
636     for (i = 0; i < g->num_edges; i++) {
637         grid_edge *e = g->edges + i;
638         ++(e->dot1->order);
639         ++(e->dot2->order);
640     }
641     /* Now we have the sizes, pre-allocate the edge and face lists. */
642     for (i = 0; i < g->num_dots; i++) {
643         grid_dot *d = g->dots + i;
644         int j;
645         assert(d->order >= 2); /* sanity check */
646         d->edges = snewn(d->order, grid_edge*);
647         d->faces = snewn(d->order, grid_face*);
648         for (j = 0; j < d->order; j++) {
649             d->edges[j] = NULL;
650             d->faces[j] = NULL;
651         }
652     }
653     /* For each dot, need to find a face that touches it, so we can seed
654      * the edge-face-edge-face process around each dot. */
655     for (i = 0; i < g->num_faces; i++) {
656         grid_face *f = g->faces + i;
657         int j;
658         for (j = 0; j < f->order; j++) {
659             grid_dot *d = f->dots[j];
660             d->faces[0] = f;
661         }
662     }
663     /* Each dot now has a face in its first slot.  Generate the remaining
664      * faces and edges around the dot, by searching both clockwise and
665      * anticlockwise from the first face.  Need to do both directions,
666      * because of the possibility of hitting the infinite face, which
667      * blocks progress.  But there's only one such face, so we will
668      * succeed in finding every edge and face this way. */
669     for (i = 0; i < g->num_dots; i++) {
670         grid_dot *d = g->dots + i;
671         int current_face1 = 0; /* ascends clockwise */
672         int current_face2 = 0; /* descends anticlockwise */
673         
674         /* Labelling scheme: as we walk clockwise around the dot, starting
675          * at face0 (d->faces[0]), we hit:
676          * (face0), edge0, face1, edge1, face2,...
677          *
678          *       0
679          *       |
680          *    0  |  1
681          *       |
682          *  -----d-----1
683          *       |
684          *       |  2
685          *       |
686          *       2
687          *
688          * So, for example, face1 should be joined to edge0 and edge1,
689          * and those edges should appear in an anticlockwise sense around
690          * that face (see diagram). */
691  
692         /* clockwise search */
693         while (TRUE) {
694             grid_face *f = d->faces[current_face1];
695             grid_edge *e;
696             int j;
697             assert(f != NULL);
698             /* find dot around this face */
699             for (j = 0; j < f->order; j++) {
700                 if (f->dots[j] == d)
701                     break;
702             }
703             assert(j != f->order); /* must find dot */
704             
705             /* Around f, required edge is anticlockwise from the dot.  See
706              * the other labelling scheme higher up, for why we subtract 1
707              * from j. */
708             j--;
709             if (j == -1)
710                 j = f->order - 1;
711             e = f->edges[j];
712             d->edges[current_face1] = e; /* set edge */
713             current_face1++;
714             if (current_face1 == d->order)
715                 break;
716             else {
717                 /* set face */
718                 d->faces[current_face1] =
719                     (e->face1 == f) ? e->face2 : e->face1;
720                 if (d->faces[current_face1] == NULL)
721                     break; /* cannot progress beyond infinite face */
722             }
723         }
724         /* If the clockwise search made it all the way round, don't need to
725          * bother with the anticlockwise search. */
726         if (current_face1 == d->order)
727             continue; /* this dot is complete, move on to next dot */
728         
729         /* anticlockwise search */
730         while (TRUE) {
731             grid_face *f = d->faces[current_face2];
732             grid_edge *e;
733             int j;
734             assert(f != NULL);
735             /* find dot around this face */
736             for (j = 0; j < f->order; j++) {
737                 if (f->dots[j] == d)
738                     break;
739             }
740             assert(j != f->order); /* must find dot */
741             
742             /* Around f, required edge is clockwise from the dot. */
743             e = f->edges[j];
744             
745             current_face2--;
746             if (current_face2 == -1)
747                 current_face2 = d->order - 1;
748             d->edges[current_face2] = e; /* set edge */
749
750             /* set face */
751             if (current_face2 == current_face1)
752                 break;
753             d->faces[current_face2] =
754                     (e->face1 == f) ? e->face2 : e->face1;
755             /* There's only 1 infinite face, so we must get all the way
756              * to current_face1 before we hit it. */
757             assert(d->faces[current_face2]);
758         }
759     }
760
761     /* ====== Stage 4 ======
762      * Compute other grid settings
763      */
764
765     /* Bounding rectangle */
766     for (i = 0; i < g->num_dots; i++) {
767         grid_dot *d = g->dots + i;
768         if (i == 0) {
769             g->lowest_x = g->highest_x = d->x;
770             g->lowest_y = g->highest_y = d->y;
771         } else {
772             g->lowest_x = min(g->lowest_x, d->x);
773             g->highest_x = max(g->highest_x, d->x);
774             g->lowest_y = min(g->lowest_y, d->y);
775             g->highest_y = max(g->highest_y, d->y);
776         }
777     }
778
779     grid_debug_derived(g);
780 }
781
782 /* Helpers for making grid-generation easier.  These functions are only
783  * intended for use during grid generation. */
784
785 /* Comparison function for the (tree234) sorted dot list */
786 static int grid_point_cmp_fn(void *v1, void *v2)
787 {
788     grid_dot *p1 = v1;
789     grid_dot *p2 = v2;
790     if (p1->y != p2->y)
791         return p2->y - p1->y;
792     else
793         return p2->x - p1->x;
794 }
795 /* Add a new face to the grid, with its dot list allocated.
796  * Assumes there's enough space allocated for the new face in grid->faces */
797 static void grid_face_add_new(grid *g, int face_size)
798 {
799     int i;
800     grid_face *new_face = g->faces + g->num_faces;
801     new_face->order = face_size;
802     new_face->dots = snewn(face_size, grid_dot*);
803     for (i = 0; i < face_size; i++)
804         new_face->dots[i] = NULL;
805     new_face->edges = NULL;
806     new_face->has_incentre = FALSE;
807     g->num_faces++;
808 }
809 /* Assumes dot list has enough space */
810 static grid_dot *grid_dot_add_new(grid *g, int x, int y)
811 {
812     grid_dot *new_dot = g->dots + g->num_dots;
813     new_dot->order = 0;
814     new_dot->edges = NULL;
815     new_dot->faces = NULL;
816     new_dot->x = x;
817     new_dot->y = y;
818     g->num_dots++;
819     return new_dot;
820 }
821 /* Retrieve a dot with these (x,y) coordinates.  Either return an existing dot
822  * in the dot_list, or add a new dot to the grid (and the dot_list) and
823  * return that.
824  * Assumes g->dots has enough capacity allocated */
825 static grid_dot *grid_get_dot(grid *g, tree234 *dot_list, int x, int y)
826 {
827     grid_dot test, *ret;
828
829     test.order = 0;
830     test.edges = NULL;
831     test.faces = NULL;
832     test.x = x;
833     test.y = y;
834     ret = find234(dot_list, &test, NULL);
835     if (ret)
836         return ret;
837
838     ret = grid_dot_add_new(g, x, y);
839     add234(dot_list, ret);
840     return ret;
841 }
842
843 /* Sets the last face of the grid to include this dot, at this position
844  * around the face. Assumes num_faces is at least 1 (a new face has
845  * previously been added, with the required number of dots allocated) */
846 static void grid_face_set_dot(grid *g, grid_dot *d, int position)
847 {
848     grid_face *last_face = g->faces + g->num_faces - 1;
849     last_face->dots[position] = d;
850 }
851
852 /*
853  * Helper routines for grid_find_incentre.
854  */
855 static int solve_2x2_matrix(double mx[4], double vin[2], double vout[2])
856 {
857     double inv[4];
858     double det;
859     det = (mx[0]*mx[3] - mx[1]*mx[2]);
860     if (det == 0)
861         return FALSE;
862
863     inv[0] = mx[3] / det;
864     inv[1] = -mx[1] / det;
865     inv[2] = -mx[2] / det;
866     inv[3] = mx[0] / det;
867
868     vout[0] = inv[0]*vin[0] + inv[1]*vin[1];
869     vout[1] = inv[2]*vin[0] + inv[3]*vin[1];
870
871     return TRUE;
872 }
873 static int solve_3x3_matrix(double mx[9], double vin[3], double vout[3])
874 {
875     double inv[9];
876     double det;
877
878     det = (mx[0]*mx[4]*mx[8] + mx[1]*mx[5]*mx[6] + mx[2]*mx[3]*mx[7] -
879            mx[0]*mx[5]*mx[7] - mx[1]*mx[3]*mx[8] - mx[2]*mx[4]*mx[6]);
880     if (det == 0)
881         return FALSE;
882
883     inv[0] = (mx[4]*mx[8] - mx[5]*mx[7]) / det;
884     inv[1] = (mx[2]*mx[7] - mx[1]*mx[8]) / det;
885     inv[2] = (mx[1]*mx[5] - mx[2]*mx[4]) / det;
886     inv[3] = (mx[5]*mx[6] - mx[3]*mx[8]) / det;
887     inv[4] = (mx[0]*mx[8] - mx[2]*mx[6]) / det;
888     inv[5] = (mx[2]*mx[3] - mx[0]*mx[5]) / det;
889     inv[6] = (mx[3]*mx[7] - mx[4]*mx[6]) / det;
890     inv[7] = (mx[1]*mx[6] - mx[0]*mx[7]) / det;
891     inv[8] = (mx[0]*mx[4] - mx[1]*mx[3]) / det;
892
893     vout[0] = inv[0]*vin[0] + inv[1]*vin[1] + inv[2]*vin[2];
894     vout[1] = inv[3]*vin[0] + inv[4]*vin[1] + inv[5]*vin[2];
895     vout[2] = inv[6]*vin[0] + inv[7]*vin[1] + inv[8]*vin[2];
896
897     return TRUE;
898 }
899
900 void grid_find_incentre(grid_face *f)
901 {
902     double xbest, ybest, bestdist;
903     int i, j, k, m;
904     grid_dot *edgedot1[3], *edgedot2[3];
905     grid_dot *dots[3];
906     int nedges, ndots;
907
908     if (f->has_incentre)
909         return;
910
911     /*
912      * Find the point in the polygon with the maximum distance to any
913      * edge or corner.
914      *
915      * Such a point must exist which is in contact with at least three
916      * edges and/or vertices. (Proof: if it's only in contact with two
917      * edges and/or vertices, it can't even be at a _local_ maximum -
918      * any such circle can always be expanded in some direction.) So
919      * we iterate through all 3-subsets of the combined set of edges
920      * and vertices; for each subset we generate one or two candidate
921      * points that might be the incentre, and then we vet each one to
922      * see if it's inside the polygon and what its maximum radius is.
923      *
924      * (There's one case which this algorithm will get noticeably
925      * wrong, and that's when a continuum of equally good answers
926      * exists due to parallel edges. Consider a long thin rectangle,
927      * for instance, or a parallelogram. This algorithm will pick a
928      * point near one end, and choose the end arbitrarily; obviously a
929      * nicer point to choose would be in the centre. To fix this I
930      * would have to introduce a special-case system which detected
931      * parallel edges in advance, set aside all candidate points
932      * generated using both edges in a parallel pair, and generated
933      * some additional candidate points half way between them. Also,
934      * of course, I'd have to cope with rounding error making such a
935      * point look worse than one of its endpoints. So I haven't done
936      * this for the moment, and will cross it if necessary when I come
937      * to it.)
938      *
939      * We don't actually iterate literally over _edges_, in the sense
940      * of grid_edge structures. Instead, we fill in edgedot1[] and
941      * edgedot2[] with a pair of dots adjacent in the face's list of
942      * vertices. This ensures that we get the edges in consistent
943      * orientation, which we could not do from the grid structure
944      * alone. (A moment's consideration of an order-3 vertex should
945      * make it clear that if a notional arrow was written on each
946      * edge, _at least one_ of the three faces bordering that vertex
947      * would have to have the two arrows tip-to-tip or tail-to-tail
948      * rather than tip-to-tail.)
949      */
950     nedges = ndots = 0;
951     bestdist = 0;
952     xbest = ybest = 0;
953
954     for (i = 0; i+2 < 2*f->order; i++) {
955         if (i < f->order) {
956             edgedot1[nedges] = f->dots[i];
957             edgedot2[nedges++] = f->dots[(i+1)%f->order];
958         } else
959             dots[ndots++] = f->dots[i - f->order];
960
961         for (j = i+1; j+1 < 2*f->order; j++) {
962             if (j < f->order) {
963                 edgedot1[nedges] = f->dots[j];
964                 edgedot2[nedges++] = f->dots[(j+1)%f->order];
965             } else
966                 dots[ndots++] = f->dots[j - f->order];
967
968             for (k = j+1; k < 2*f->order; k++) {
969                 double cx[2], cy[2];   /* candidate positions */
970                 int cn = 0;            /* number of candidates */
971
972                 if (k < f->order) {
973                     edgedot1[nedges] = f->dots[k];
974                     edgedot2[nedges++] = f->dots[(k+1)%f->order];
975                 } else
976                     dots[ndots++] = f->dots[k - f->order];
977
978                 /*
979                  * Find a point, or pair of points, equidistant from
980                  * all the specified edges and/or vertices.
981                  */
982                 if (nedges == 3) {
983                     /*
984                      * Three edges. This is a linear matrix equation:
985                      * each row of the matrix represents the fact that
986                      * the point (x,y) we seek is at distance r from
987                      * that edge, and we solve three of those
988                      * simultaneously to obtain x,y,r. (We ignore r.)
989                      */
990                     double matrix[9], vector[3], vector2[3];
991                     int m;
992
993                     for (m = 0; m < 3; m++) {
994                         int x1 = edgedot1[m]->x, x2 = edgedot2[m]->x;
995                         int y1 = edgedot1[m]->y, y2 = edgedot2[m]->y;
996                         int dx = x2-x1, dy = y2-y1;
997
998                         /*
999                          * ((x,y) - (x1,y1)) . (dy,-dx) = r |(dx,dy)|
1000                          *
1001                          * => x dy - y dx - r |(dx,dy)| = (x1 dy - y1 dx)
1002                          */
1003                         matrix[3*m+0] = dy;
1004                         matrix[3*m+1] = -dx;
1005                         matrix[3*m+2] = -sqrt((double)dx*dx+(double)dy*dy);
1006                         vector[m] = (double)x1*dy - (double)y1*dx;
1007                     }
1008
1009                     if (solve_3x3_matrix(matrix, vector, vector2)) {
1010                         cx[cn] = vector2[0];
1011                         cy[cn] = vector2[1];
1012                         cn++;
1013                     }
1014                 } else if (nedges == 2) {
1015                     /*
1016                      * Two edges and a dot. This will end up in a
1017                      * quadratic equation.
1018                      *
1019                      * First, look at the two edges. Having our point
1020                      * be some distance r from both of them gives rise
1021                      * to a pair of linear equations in x,y,r of the
1022                      * form
1023                      *
1024                      *   (x-x1) dy - (y-y1) dx = r sqrt(dx^2+dy^2)
1025                      *
1026                      * We eliminate r between those equations to give
1027                      * us a single linear equation in x,y describing
1028                      * the locus of points equidistant from both lines
1029                      * - i.e. the angle bisector. 
1030                      *
1031                      * We then choose one of x,y to be a parameter t,
1032                      * and derive linear formulae for x,y,r in terms
1033                      * of t. This enables us to write down the
1034                      * circular equation (x-xd)^2+(y-yd)^2=r^2 as a
1035                      * quadratic in t; solving that and substituting
1036                      * in for x,y gives us two candidate points.
1037                      */
1038                     double eqs[2][4];  /* a,b,c,d : ax+by+cr=d */
1039                     double eq[3];      /* a,b,c: ax+by=c */
1040                     double xt[2], yt[2], rt[2]; /* a,b: {x,y,r}=at+b */
1041                     double q[3];                /* a,b,c: at^2+bt+c=0 */
1042                     double disc;
1043
1044                     /* Find equations of the two input lines. */
1045                     for (m = 0; m < 2; m++) {
1046                         int x1 = edgedot1[m]->x, x2 = edgedot2[m]->x;
1047                         int y1 = edgedot1[m]->y, y2 = edgedot2[m]->y;
1048                         int dx = x2-x1, dy = y2-y1;
1049
1050                         eqs[m][0] = dy;
1051                         eqs[m][1] = -dx;
1052                         eqs[m][2] = -sqrt(dx*dx+dy*dy);
1053                         eqs[m][3] = x1*dy - y1*dx;
1054                     }
1055
1056                     /* Derive the angle bisector by eliminating r. */
1057                     eq[0] = eqs[0][0]*eqs[1][2] - eqs[1][0]*eqs[0][2];
1058                     eq[1] = eqs[0][1]*eqs[1][2] - eqs[1][1]*eqs[0][2];
1059                     eq[2] = eqs[0][3]*eqs[1][2] - eqs[1][3]*eqs[0][2];
1060
1061                     /* Parametrise x and y in terms of some t. */
1062                     if (abs(eq[0]) < abs(eq[1])) {
1063                         /* Parameter is x. */
1064                         xt[0] = 1; xt[1] = 0;
1065                         yt[0] = -eq[0]/eq[1]; yt[1] = eq[2]/eq[1];
1066                     } else {
1067                         /* Parameter is y. */
1068                         yt[0] = 1; yt[1] = 0;
1069                         xt[0] = -eq[1]/eq[0]; xt[1] = eq[2]/eq[0];
1070                     }
1071
1072                     /* Find a linear representation of r using eqs[0]. */
1073                     rt[0] = -(eqs[0][0]*xt[0] + eqs[0][1]*yt[0])/eqs[0][2];
1074                     rt[1] = (eqs[0][3] - eqs[0][0]*xt[1] -
1075                              eqs[0][1]*yt[1])/eqs[0][2];
1076
1077                     /* Construct the quadratic equation. */
1078                     q[0] = -rt[0]*rt[0];
1079                     q[1] = -2*rt[0]*rt[1];
1080                     q[2] = -rt[1]*rt[1];
1081                     q[0] += xt[0]*xt[0];
1082                     q[1] += 2*xt[0]*(xt[1]-dots[0]->x);
1083                     q[2] += (xt[1]-dots[0]->x)*(xt[1]-dots[0]->x);
1084                     q[0] += yt[0]*yt[0];
1085                     q[1] += 2*yt[0]*(yt[1]-dots[0]->y);
1086                     q[2] += (yt[1]-dots[0]->y)*(yt[1]-dots[0]->y);
1087
1088                     /* And solve it. */
1089                     disc = q[1]*q[1] - 4*q[0]*q[2];
1090                     if (disc >= 0) {
1091                         double t;
1092
1093                         disc = sqrt(disc);
1094
1095                         t = (-q[1] + disc) / (2*q[0]);
1096                         cx[cn] = xt[0]*t + xt[1];
1097                         cy[cn] = yt[0]*t + yt[1];
1098                         cn++;
1099
1100                         t = (-q[1] - disc) / (2*q[0]);
1101                         cx[cn] = xt[0]*t + xt[1];
1102                         cy[cn] = yt[0]*t + yt[1];
1103                         cn++;
1104                     }
1105                 } else if (nedges == 1) {
1106                     /*
1107                      * Two dots and an edge. This one's another
1108                      * quadratic equation.
1109                      *
1110                      * The point we want must lie on the perpendicular
1111                      * bisector of the two dots; that much is obvious.
1112                      * So we can construct a parametrisation of that
1113                      * bisecting line, giving linear formulae for x,y
1114                      * in terms of t. We can also express the distance
1115                      * from the edge as such a linear formula.
1116                      *
1117                      * Then we set that equal to the radius of the
1118                      * circle passing through the two points, which is
1119                      * a Pythagoras exercise; that gives rise to a
1120                      * quadratic in t, which we solve.
1121                      */
1122                     double xt[2], yt[2], rt[2]; /* a,b: {x,y,r}=at+b */
1123                     double q[3];                /* a,b,c: at^2+bt+c=0 */
1124                     double disc;
1125                     double halfsep;
1126
1127                     /* Find parametric formulae for x,y. */
1128                     {
1129                         int x1 = dots[0]->x, x2 = dots[1]->x;
1130                         int y1 = dots[0]->y, y2 = dots[1]->y;
1131                         int dx = x2-x1, dy = y2-y1;
1132                         double d = sqrt((double)dx*dx + (double)dy*dy);
1133
1134                         xt[1] = (x1+x2)/2.0;
1135                         yt[1] = (y1+y2)/2.0;
1136                         /* It's convenient if we have t at standard scale. */
1137                         xt[0] = -dy/d;
1138                         yt[0] = dx/d;
1139
1140                         /* Also note down half the separation between
1141                          * the dots, for use in computing the circle radius. */
1142                         halfsep = 0.5*d;
1143                     }
1144
1145                     /* Find a parametric formula for r. */
1146                     {
1147                         int x1 = edgedot1[0]->x, x2 = edgedot2[0]->x;
1148                         int y1 = edgedot1[0]->y, y2 = edgedot2[0]->y;
1149                         int dx = x2-x1, dy = y2-y1;
1150                         double d = sqrt((double)dx*dx + (double)dy*dy);
1151                         rt[0] = (xt[0]*dy - yt[0]*dx) / d;
1152                         rt[1] = ((xt[1]-x1)*dy - (yt[1]-y1)*dx) / d;
1153                     }
1154
1155                     /* Construct the quadratic equation. */
1156                     q[0] = rt[0]*rt[0];
1157                     q[1] = 2*rt[0]*rt[1];
1158                     q[2] = rt[1]*rt[1];
1159                     q[0] -= 1;
1160                     q[2] -= halfsep*halfsep;
1161
1162                     /* And solve it. */
1163                     disc = q[1]*q[1] - 4*q[0]*q[2];
1164                     if (disc >= 0) {
1165                         double t;
1166
1167                         disc = sqrt(disc);
1168
1169                         t = (-q[1] + disc) / (2*q[0]);
1170                         cx[cn] = xt[0]*t + xt[1];
1171                         cy[cn] = yt[0]*t + yt[1];
1172                         cn++;
1173
1174                         t = (-q[1] - disc) / (2*q[0]);
1175                         cx[cn] = xt[0]*t + xt[1];
1176                         cy[cn] = yt[0]*t + yt[1];
1177                         cn++;
1178                     }
1179                 } else if (nedges == 0) {
1180                     /*
1181                      * Three dots. This is another linear matrix
1182                      * equation, this time with each row of the matrix
1183                      * representing the perpendicular bisector between
1184                      * two of the points. Of course we only need two
1185                      * such lines to find their intersection, so we
1186                      * need only solve a 2x2 matrix equation.
1187                      */
1188
1189                     double matrix[4], vector[2], vector2[2];
1190                     int m;
1191
1192                     for (m = 0; m < 2; m++) {
1193                         int x1 = dots[m]->x, x2 = dots[m+1]->x;
1194                         int y1 = dots[m]->y, y2 = dots[m+1]->y;
1195                         int dx = x2-x1, dy = y2-y1;
1196
1197                         /*
1198                          * ((x,y) - (x1,y1)) . (dx,dy) = 1/2 |(dx,dy)|^2
1199                          *
1200                          * => 2x dx + 2y dy = dx^2+dy^2 + (2 x1 dx + 2 y1 dy)
1201                          */
1202                         matrix[2*m+0] = 2*dx;
1203                         matrix[2*m+1] = 2*dy;
1204                         vector[m] = ((double)dx*dx + (double)dy*dy +
1205                                      2.0*x1*dx + 2.0*y1*dy);
1206                     }
1207
1208                     if (solve_2x2_matrix(matrix, vector, vector2)) {
1209                         cx[cn] = vector2[0];
1210                         cy[cn] = vector2[1];
1211                         cn++;
1212                     }
1213                 }
1214
1215                 /*
1216                  * Now go through our candidate points and see if any
1217                  * of them are better than what we've got so far.
1218                  */
1219                 for (m = 0; m < cn; m++) {
1220                     double x = cx[m], y = cy[m];
1221
1222                     /*
1223                      * First, disqualify the point if it's not inside
1224                      * the polygon, which we work out by counting the
1225                      * edges to the right of the point. (For
1226                      * tiebreaking purposes when edges start or end on
1227                      * our y-coordinate or go right through it, we
1228                      * consider our point to be offset by a small
1229                      * _positive_ epsilon in both the x- and
1230                      * y-direction.)
1231                      */
1232                     int e, in = 0;
1233                     for (e = 0; e < f->order; e++) {
1234                         int xs = f->edges[e]->dot1->x;
1235                         int xe = f->edges[e]->dot2->x;
1236                         int ys = f->edges[e]->dot1->y;
1237                         int ye = f->edges[e]->dot2->y;
1238                         if ((y >= ys && y < ye) || (y >= ye && y < ys)) {
1239                             /*
1240                              * The line goes past our y-position. Now we need
1241                              * to know if its x-coordinate when it does so is
1242                              * to our right.
1243                              *
1244                              * The x-coordinate in question is mathematically
1245                              * (y - ys) * (xe - xs) / (ye - ys), and we want
1246                              * to know whether (x - xs) >= that. Of course we
1247                              * avoid the division, so we can work in integers;
1248                              * to do this we must multiply both sides of the
1249                              * inequality by ye - ys, which means we must
1250                              * first check that's not negative.
1251                              */
1252                             int num = xe - xs, denom = ye - ys;
1253                             if (denom < 0) {
1254                                 num = -num;
1255                                 denom = -denom;
1256                             }
1257                             if ((x - xs) * denom >= (y - ys) * num)
1258                                 in ^= 1;
1259                         }
1260                     }
1261
1262                     if (in) {
1263                         double mindist = HUGE_VAL;
1264                         int e, d;
1265
1266                         /*
1267                          * This point is inside the polygon, so now we check
1268                          * its minimum distance to every edge and corner.
1269                          * First the corners ...
1270                          */
1271                         for (d = 0; d < f->order; d++) {
1272                             int xp = f->dots[d]->x;
1273                             int yp = f->dots[d]->y;
1274                             double dx = x - xp, dy = y - yp;
1275                             double dist = dx*dx + dy*dy;
1276                             if (mindist > dist)
1277                                 mindist = dist;
1278                         }
1279
1280                         /*
1281                          * ... and now also check the perpendicular distance
1282                          * to every edge, if the perpendicular lies between
1283                          * the edge's endpoints.
1284                          */
1285                         for (e = 0; e < f->order; e++) {
1286                             int xs = f->edges[e]->dot1->x;
1287                             int xe = f->edges[e]->dot2->x;
1288                             int ys = f->edges[e]->dot1->y;
1289                             int ye = f->edges[e]->dot2->y;
1290
1291                             /*
1292                              * If s and e are our endpoints, and p our
1293                              * candidate circle centre, the foot of a
1294                              * perpendicular from p to the line se lies
1295                              * between s and e if and only if (p-s).(e-s) lies
1296                              * strictly between 0 and (e-s).(e-s).
1297                              */
1298                             int edx = xe - xs, edy = ye - ys;
1299                             double pdx = x - xs, pdy = y - ys;
1300                             double pde = pdx * edx + pdy * edy;
1301                             long ede = (long)edx * edx + (long)edy * edy;
1302                             if (0 < pde && pde < ede) {
1303                                 /*
1304                                  * Yes, the nearest point on this edge is
1305                                  * closer than either endpoint, so we must
1306                                  * take it into account by measuring the
1307                                  * perpendicular distance to the edge and
1308                                  * checking its square against mindist.
1309                                  */
1310
1311                                 double pdre = pdx * edy - pdy * edx;
1312                                 double sqlen = pdre * pdre / ede;
1313
1314                                 if (mindist > sqlen)
1315                                     mindist = sqlen;
1316                             }
1317                         }
1318
1319                         /*
1320                          * Right. Now we know the biggest circle around this
1321                          * point, so we can check it against bestdist.
1322                          */
1323                         if (bestdist < mindist) {
1324                             bestdist = mindist;
1325                             xbest = x;
1326                             ybest = y;
1327                         }
1328                     }
1329                 }
1330
1331                 if (k < f->order)
1332                     nedges--;
1333                 else
1334                     ndots--;
1335             }
1336             if (j < f->order)
1337                 nedges--;
1338             else
1339                 ndots--;
1340         }
1341         if (i < f->order)
1342             nedges--;
1343         else
1344             ndots--;
1345     }
1346
1347     assert(bestdist > 0);
1348
1349     f->has_incentre = TRUE;
1350     f->ix = xbest + 0.5;               /* round to nearest */
1351     f->iy = ybest + 0.5;
1352 }
1353
1354 /* ------ Generate various types of grid ------ */
1355
1356 /* General method is to generate faces, by calculating their dot coordinates.
1357  * As new faces are added, we keep track of all the dots so we can tell when
1358  * a new face reuses an existing dot.  For example, two squares touching at an
1359  * edge would generate six unique dots: four dots from the first face, then
1360  * two additional dots for the second face, because we detect the other two
1361  * dots have already been taken up.  This list is stored in a tree234
1362  * called "points".  No extra memory-allocation needed here - we store the
1363  * actual grid_dot* pointers, which all point into the g->dots list.
1364  * For this reason, we have to calculate coordinates in such a way as to
1365  * eliminate any rounding errors, so we can detect when a dot on one
1366  * face precisely lands on a dot of a different face.  No floating-point
1367  * arithmetic here!
1368  */
1369
1370 #define SQUARE_TILESIZE 20
1371
1372 void grid_size_square(int width, int height,
1373                       int *tilesize, int *xextent, int *yextent)
1374 {
1375     int a = SQUARE_TILESIZE;
1376
1377     *tilesize = a;
1378     *xextent = width * a;
1379     *yextent = height * a;
1380 }
1381
1382 grid *grid_new_square(int width, int height, char *desc)
1383 {
1384     int x, y;
1385     /* Side length */
1386     int a = SQUARE_TILESIZE;
1387
1388     /* Upper bounds - don't have to be exact */
1389     int max_faces = width * height;
1390     int max_dots = (width + 1) * (height + 1);
1391
1392     tree234 *points;
1393
1394     grid *g = grid_empty();
1395     g->tilesize = a;
1396     g->faces = snewn(max_faces, grid_face);
1397     g->dots = snewn(max_dots, grid_dot);
1398
1399     points = newtree234(grid_point_cmp_fn);
1400
1401     /* generate square faces */
1402     for (y = 0; y < height; y++) {
1403         for (x = 0; x < width; x++) {
1404             grid_dot *d;
1405             /* face position */
1406             int px = a * x;
1407             int py = a * y;
1408
1409             grid_face_add_new(g, 4);
1410             d = grid_get_dot(g, points, px, py);
1411             grid_face_set_dot(g, d, 0);
1412             d = grid_get_dot(g, points, px + a, py);
1413             grid_face_set_dot(g, d, 1);
1414             d = grid_get_dot(g, points, px + a, py + a);
1415             grid_face_set_dot(g, d, 2);
1416             d = grid_get_dot(g, points, px, py + a);
1417             grid_face_set_dot(g, d, 3);
1418         }
1419     }
1420
1421     freetree234(points);
1422     assert(g->num_faces <= max_faces);
1423     assert(g->num_dots <= max_dots);
1424
1425     grid_make_consistent(g);
1426     return g;
1427 }
1428
1429 #define HONEY_TILESIZE 45
1430 /* Vector for side of hexagon - ratio is close to sqrt(3) */
1431 #define HONEY_A 15
1432 #define HONEY_B 26
1433
1434 void grid_size_honeycomb(int width, int height,
1435                          int *tilesize, int *xextent, int *yextent)
1436 {
1437     int a = HONEY_A;
1438     int b = HONEY_B;
1439
1440     *tilesize = HONEY_TILESIZE;
1441     *xextent = (3 * a * (width-1)) + 4*a;
1442     *yextent = (2 * b * (height-1)) + 3*b;
1443 }
1444
1445 grid *grid_new_honeycomb(int width, int height, char *desc)
1446 {
1447     int x, y;
1448     int a = HONEY_A;
1449     int b = HONEY_B;
1450
1451     /* Upper bounds - don't have to be exact */
1452     int max_faces = width * height;
1453     int max_dots = 2 * (width + 1) * (height + 1);
1454
1455     tree234 *points;
1456
1457     grid *g = grid_empty();
1458     g->tilesize = HONEY_TILESIZE;
1459     g->faces = snewn(max_faces, grid_face);
1460     g->dots = snewn(max_dots, grid_dot);
1461
1462     points = newtree234(grid_point_cmp_fn);
1463
1464     /* generate hexagonal faces */
1465     for (y = 0; y < height; y++) {
1466         for (x = 0; x < width; x++) {
1467             grid_dot *d;
1468             /* face centre */
1469             int cx = 3 * a * x;
1470             int cy = 2 * b * y;
1471             if (x % 2)
1472                 cy += b;
1473             grid_face_add_new(g, 6);
1474
1475             d = grid_get_dot(g, points, cx - a, cy - b);
1476             grid_face_set_dot(g, d, 0);
1477             d = grid_get_dot(g, points, cx + a, cy - b);
1478             grid_face_set_dot(g, d, 1);
1479             d = grid_get_dot(g, points, cx + 2*a, cy);
1480             grid_face_set_dot(g, d, 2);
1481             d = grid_get_dot(g, points, cx + a, cy + b);
1482             grid_face_set_dot(g, d, 3);
1483             d = grid_get_dot(g, points, cx - a, cy + b);
1484             grid_face_set_dot(g, d, 4);
1485             d = grid_get_dot(g, points, cx - 2*a, cy);
1486             grid_face_set_dot(g, d, 5);
1487         }
1488     }
1489
1490     freetree234(points);
1491     assert(g->num_faces <= max_faces);
1492     assert(g->num_dots <= max_dots);
1493
1494     grid_make_consistent(g);
1495     return g;
1496 }
1497
1498 #define TRIANGLE_TILESIZE 18
1499 /* Vector for side of triangle - ratio is close to sqrt(3) */
1500 #define TRIANGLE_VEC_X 15
1501 #define TRIANGLE_VEC_Y 26
1502
1503 void grid_size_triangular(int width, int height,
1504                           int *tilesize, int *xextent, int *yextent)
1505 {
1506     int vec_x = TRIANGLE_VEC_X;
1507     int vec_y = TRIANGLE_VEC_Y;
1508
1509     *tilesize = TRIANGLE_TILESIZE;
1510     *xextent = width * 2 * vec_x + vec_x;
1511     *yextent = height * vec_y;
1512 }
1513
1514 /* Doesn't use the previous method of generation, it pre-dates it!
1515  * A triangular grid is just about simple enough to do by "brute force" */
1516 grid *grid_new_triangular(int width, int height, char *desc)
1517 {
1518     int x,y;
1519     
1520     /* Vector for side of triangle - ratio is close to sqrt(3) */
1521     int vec_x = TRIANGLE_VEC_X;
1522     int vec_y = TRIANGLE_VEC_Y;
1523     
1524     int index;
1525
1526     /* convenient alias */
1527     int w = width + 1;
1528
1529     grid *g = grid_empty();
1530     g->tilesize = TRIANGLE_TILESIZE;
1531
1532     g->num_faces = width * height * 2;
1533     g->num_dots = (width + 1) * (height + 1);
1534     g->faces = snewn(g->num_faces, grid_face);
1535     g->dots = snewn(g->num_dots, grid_dot);
1536
1537     /* generate dots */
1538     index = 0;
1539     for (y = 0; y <= height; y++) {
1540         for (x = 0; x <= width; x++) {
1541             grid_dot *d = g->dots + index;
1542             /* odd rows are offset to the right */
1543             d->order = 0;
1544             d->edges = NULL;
1545             d->faces = NULL;
1546             d->x = x * 2 * vec_x + ((y % 2) ? vec_x : 0);
1547             d->y = y * vec_y;
1548             index++;
1549         }
1550     }
1551     
1552     /* generate faces */
1553     index = 0;
1554     for (y = 0; y < height; y++) {
1555         for (x = 0; x < width; x++) {
1556             /* initialise two faces for this (x,y) */
1557             grid_face *f1 = g->faces + index;
1558             grid_face *f2 = f1 + 1;
1559             f1->edges = NULL;
1560             f1->order = 3;
1561             f1->dots = snewn(f1->order, grid_dot*);
1562             f1->has_incentre = FALSE;
1563             f2->edges = NULL;
1564             f2->order = 3;
1565             f2->dots = snewn(f2->order, grid_dot*);
1566             f2->has_incentre = FALSE;
1567
1568             /* face descriptions depend on whether the row-number is
1569              * odd or even */
1570             if (y % 2) {
1571                 f1->dots[0] = g->dots + y       * w + x;
1572                 f1->dots[1] = g->dots + (y + 1) * w + x + 1;
1573                 f1->dots[2] = g->dots + (y + 1) * w + x;
1574                 f2->dots[0] = g->dots + y       * w + x;
1575                 f2->dots[1] = g->dots + y       * w + x + 1;
1576                 f2->dots[2] = g->dots + (y + 1) * w + x + 1;
1577             } else {
1578                 f1->dots[0] = g->dots + y       * w + x;
1579                 f1->dots[1] = g->dots + y       * w + x + 1;
1580                 f1->dots[2] = g->dots + (y + 1) * w + x;
1581                 f2->dots[0] = g->dots + y       * w + x + 1;
1582                 f2->dots[1] = g->dots + (y + 1) * w + x + 1;
1583                 f2->dots[2] = g->dots + (y + 1) * w + x;
1584             }
1585             index += 2;
1586         }
1587     }
1588
1589     grid_make_consistent(g);
1590     return g;
1591 }
1592
1593 #define SNUBSQUARE_TILESIZE 18
1594 /* Vector for side of triangle - ratio is close to sqrt(3) */
1595 #define SNUBSQUARE_A 15
1596 #define SNUBSQUARE_B 26
1597
1598 void grid_size_snubsquare(int width, int height,
1599                           int *tilesize, int *xextent, int *yextent)
1600 {
1601     int a = SNUBSQUARE_A;
1602     int b = SNUBSQUARE_B;
1603
1604     *tilesize = SNUBSQUARE_TILESIZE;
1605     *xextent = (a+b) * (width-1) + a + b;
1606     *yextent = (a+b) * (height-1) + a + b;
1607 }
1608
1609 grid *grid_new_snubsquare(int width, int height, char *desc)
1610 {
1611     int x, y;
1612     int a = SNUBSQUARE_A;
1613     int b = SNUBSQUARE_B;
1614
1615     /* Upper bounds - don't have to be exact */
1616     int max_faces = 3 * width * height;
1617     int max_dots = 2 * (width + 1) * (height + 1);
1618
1619     tree234 *points;
1620
1621     grid *g = grid_empty();
1622     g->tilesize = SNUBSQUARE_TILESIZE;
1623     g->faces = snewn(max_faces, grid_face);
1624     g->dots = snewn(max_dots, grid_dot);
1625
1626     points = newtree234(grid_point_cmp_fn);
1627
1628     for (y = 0; y < height; y++) {
1629         for (x = 0; x < width; x++) {
1630             grid_dot *d;
1631             /* face position */
1632             int px = (a + b) * x;
1633             int py = (a + b) * y;
1634
1635             /* generate square faces */
1636             grid_face_add_new(g, 4);
1637             if ((x + y) % 2) {
1638                 d = grid_get_dot(g, points, px + a, py);
1639                 grid_face_set_dot(g, d, 0);
1640                 d = grid_get_dot(g, points, px + a + b, py + a);
1641                 grid_face_set_dot(g, d, 1);
1642                 d = grid_get_dot(g, points, px + b, py + a + b);
1643                 grid_face_set_dot(g, d, 2);
1644                 d = grid_get_dot(g, points, px, py + b);
1645                 grid_face_set_dot(g, d, 3);
1646             } else {
1647                 d = grid_get_dot(g, points, px + b, py);
1648                 grid_face_set_dot(g, d, 0);
1649                 d = grid_get_dot(g, points, px + a + b, py + b);
1650                 grid_face_set_dot(g, d, 1);
1651                 d = grid_get_dot(g, points, px + a, py + a + b);
1652                 grid_face_set_dot(g, d, 2);
1653                 d = grid_get_dot(g, points, px, py + a);
1654                 grid_face_set_dot(g, d, 3);
1655             }
1656
1657             /* generate up/down triangles */
1658             if (x > 0) {
1659                 grid_face_add_new(g, 3);
1660                 if ((x + y) % 2) {
1661                     d = grid_get_dot(g, points, px + a, py);
1662                     grid_face_set_dot(g, d, 0);
1663                     d = grid_get_dot(g, points, px, py + b);
1664                     grid_face_set_dot(g, d, 1);
1665                     d = grid_get_dot(g, points, px - a, py);
1666                     grid_face_set_dot(g, d, 2);
1667                 } else {
1668                     d = grid_get_dot(g, points, px, py + a);
1669                     grid_face_set_dot(g, d, 0);
1670                     d = grid_get_dot(g, points, px + a, py + a + b);
1671                     grid_face_set_dot(g, d, 1);
1672                     d = grid_get_dot(g, points, px - a, py + a + b);
1673                     grid_face_set_dot(g, d, 2);
1674                 }
1675             }
1676
1677             /* generate left/right triangles */
1678             if (y > 0) {
1679                 grid_face_add_new(g, 3);
1680                 if ((x + y) % 2) {
1681                     d = grid_get_dot(g, points, px + a, py);
1682                     grid_face_set_dot(g, d, 0);
1683                     d = grid_get_dot(g, points, px + a + b, py - a);
1684                     grid_face_set_dot(g, d, 1);
1685                     d = grid_get_dot(g, points, px + a + b, py + a);
1686                     grid_face_set_dot(g, d, 2);
1687                 } else {
1688                     d = grid_get_dot(g, points, px, py - a);
1689                     grid_face_set_dot(g, d, 0);
1690                     d = grid_get_dot(g, points, px + b, py);
1691                     grid_face_set_dot(g, d, 1);
1692                     d = grid_get_dot(g, points, px, py + a);
1693                     grid_face_set_dot(g, d, 2);
1694                 }
1695             }
1696         }
1697     }
1698
1699     freetree234(points);
1700     assert(g->num_faces <= max_faces);
1701     assert(g->num_dots <= max_dots);
1702
1703     grid_make_consistent(g);
1704     return g;
1705 }
1706
1707 #define CAIRO_TILESIZE 40
1708 /* Vector for side of pentagon - ratio is close to (4+sqrt(7))/3 */
1709 #define CAIRO_A 14
1710 #define CAIRO_B 31
1711
1712 void grid_size_cairo(int width, int height,
1713                           int *tilesize, int *xextent, int *yextent)
1714 {
1715     int b = CAIRO_B; /* a unused in determining grid size. */
1716
1717     *tilesize = CAIRO_TILESIZE;
1718     *xextent = 2*b*(width-1) + 2*b;
1719     *yextent = 2*b*(height-1) + 2*b;
1720 }
1721
1722 grid *grid_new_cairo(int width, int height, char *desc)
1723 {
1724     int x, y;
1725     int a = CAIRO_A;
1726     int b = CAIRO_B;
1727
1728     /* Upper bounds - don't have to be exact */
1729     int max_faces = 2 * width * height;
1730     int max_dots = 3 * (width + 1) * (height + 1);
1731
1732     tree234 *points;
1733
1734     grid *g = grid_empty();
1735     g->tilesize = CAIRO_TILESIZE;
1736     g->faces = snewn(max_faces, grid_face);
1737     g->dots = snewn(max_dots, grid_dot);
1738
1739     points = newtree234(grid_point_cmp_fn);
1740
1741     for (y = 0; y < height; y++) {
1742         for (x = 0; x < width; x++) {
1743             grid_dot *d;
1744             /* cell position */
1745             int px = 2 * b * x;
1746             int py = 2 * b * y;
1747
1748             /* horizontal pentagons */
1749             if (y > 0) {
1750                 grid_face_add_new(g, 5);
1751                 if ((x + y) % 2) {
1752                     d = grid_get_dot(g, points, px + a, py - b);
1753                     grid_face_set_dot(g, d, 0);
1754                     d = grid_get_dot(g, points, px + 2*b - a, py - b);
1755                     grid_face_set_dot(g, d, 1);
1756                     d = grid_get_dot(g, points, px + 2*b, py);
1757                     grid_face_set_dot(g, d, 2);
1758                     d = grid_get_dot(g, points, px + b, py + a);
1759                     grid_face_set_dot(g, d, 3);
1760                     d = grid_get_dot(g, points, px, py);
1761                     grid_face_set_dot(g, d, 4);
1762                 } else {
1763                     d = grid_get_dot(g, points, px, py);
1764                     grid_face_set_dot(g, d, 0);
1765                     d = grid_get_dot(g, points, px + b, py - a);
1766                     grid_face_set_dot(g, d, 1);
1767                     d = grid_get_dot(g, points, px + 2*b, py);
1768                     grid_face_set_dot(g, d, 2);
1769                     d = grid_get_dot(g, points, px + 2*b - a, py + b);
1770                     grid_face_set_dot(g, d, 3);
1771                     d = grid_get_dot(g, points, px + a, py + b);
1772                     grid_face_set_dot(g, d, 4);
1773                 }
1774             }
1775             /* vertical pentagons */
1776             if (x > 0) {
1777                 grid_face_add_new(g, 5);
1778                 if ((x + y) % 2) {
1779                     d = grid_get_dot(g, points, px, py);
1780                     grid_face_set_dot(g, d, 0);
1781                     d = grid_get_dot(g, points, px + b, py + a);
1782                     grid_face_set_dot(g, d, 1);
1783                     d = grid_get_dot(g, points, px + b, py + 2*b - a);
1784                     grid_face_set_dot(g, d, 2);
1785                     d = grid_get_dot(g, points, px, py + 2*b);
1786                     grid_face_set_dot(g, d, 3);
1787                     d = grid_get_dot(g, points, px - a, py + b);
1788                     grid_face_set_dot(g, d, 4);
1789                 } else {
1790                     d = grid_get_dot(g, points, px, py);
1791                     grid_face_set_dot(g, d, 0);
1792                     d = grid_get_dot(g, points, px + a, py + b);
1793                     grid_face_set_dot(g, d, 1);
1794                     d = grid_get_dot(g, points, px, py + 2*b);
1795                     grid_face_set_dot(g, d, 2);
1796                     d = grid_get_dot(g, points, px - b, py + 2*b - a);
1797                     grid_face_set_dot(g, d, 3);
1798                     d = grid_get_dot(g, points, px - b, py + a);
1799                     grid_face_set_dot(g, d, 4);
1800                 }
1801             }
1802         }
1803     }
1804
1805     freetree234(points);
1806     assert(g->num_faces <= max_faces);
1807     assert(g->num_dots <= max_dots);
1808
1809     grid_make_consistent(g);
1810     return g;
1811 }
1812
1813 #define GREATHEX_TILESIZE 18
1814 /* Vector for side of triangle - ratio is close to sqrt(3) */
1815 #define GREATHEX_A 15
1816 #define GREATHEX_B 26
1817
1818 void grid_size_greathexagonal(int width, int height,
1819                           int *tilesize, int *xextent, int *yextent)
1820 {
1821     int a = GREATHEX_A;
1822     int b = GREATHEX_B;
1823
1824     *tilesize = GREATHEX_TILESIZE;
1825     *xextent = (3*a + b) * (width-1) + 4*a;
1826     *yextent = (2*a + 2*b) * (height-1) + 3*b + a;
1827 }
1828
1829 grid *grid_new_greathexagonal(int width, int height, char *desc)
1830 {
1831     int x, y;
1832     int a = GREATHEX_A;
1833     int b = GREATHEX_B;
1834
1835     /* Upper bounds - don't have to be exact */
1836     int max_faces = 6 * (width + 1) * (height + 1);
1837     int max_dots = 6 * width * height;
1838
1839     tree234 *points;
1840
1841     grid *g = grid_empty();
1842     g->tilesize = GREATHEX_TILESIZE;
1843     g->faces = snewn(max_faces, grid_face);
1844     g->dots = snewn(max_dots, grid_dot);
1845
1846     points = newtree234(grid_point_cmp_fn);
1847
1848     for (y = 0; y < height; y++) {
1849         for (x = 0; x < width; x++) {
1850             grid_dot *d;
1851             /* centre of hexagon */
1852             int px = (3*a + b) * x;
1853             int py = (2*a + 2*b) * y;
1854             if (x % 2)
1855                 py += a + b;
1856
1857             /* hexagon */
1858             grid_face_add_new(g, 6);
1859             d = grid_get_dot(g, points, px - a, py - b);
1860             grid_face_set_dot(g, d, 0);
1861             d = grid_get_dot(g, points, px + a, py - b);
1862             grid_face_set_dot(g, d, 1);
1863             d = grid_get_dot(g, points, px + 2*a, py);
1864             grid_face_set_dot(g, d, 2);
1865             d = grid_get_dot(g, points, px + a, py + b);
1866             grid_face_set_dot(g, d, 3);
1867             d = grid_get_dot(g, points, px - a, py + b);
1868             grid_face_set_dot(g, d, 4);
1869             d = grid_get_dot(g, points, px - 2*a, py);
1870             grid_face_set_dot(g, d, 5);
1871
1872             /* square below hexagon */
1873             if (y < height - 1) {
1874                 grid_face_add_new(g, 4);
1875                 d = grid_get_dot(g, points, px - a, py + b);
1876                 grid_face_set_dot(g, d, 0);
1877                 d = grid_get_dot(g, points, px + a, py + b);
1878                 grid_face_set_dot(g, d, 1);
1879                 d = grid_get_dot(g, points, px + a, py + 2*a + b);
1880                 grid_face_set_dot(g, d, 2);
1881                 d = grid_get_dot(g, points, px - a, py + 2*a + b);
1882                 grid_face_set_dot(g, d, 3);
1883             }
1884
1885             /* square below right */
1886             if ((x < width - 1) && (((x % 2) == 0) || (y < height - 1))) {
1887                 grid_face_add_new(g, 4);
1888                 d = grid_get_dot(g, points, px + 2*a, py);
1889                 grid_face_set_dot(g, d, 0);
1890                 d = grid_get_dot(g, points, px + 2*a + b, py + a);
1891                 grid_face_set_dot(g, d, 1);
1892                 d = grid_get_dot(g, points, px + a + b, py + a + b);
1893                 grid_face_set_dot(g, d, 2);
1894                 d = grid_get_dot(g, points, px + a, py + b);
1895                 grid_face_set_dot(g, d, 3);
1896             }
1897
1898             /* square below left */
1899             if ((x > 0) && (((x % 2) == 0) || (y < height - 1))) {
1900                 grid_face_add_new(g, 4);
1901                 d = grid_get_dot(g, points, px - 2*a, py);
1902                 grid_face_set_dot(g, d, 0);
1903                 d = grid_get_dot(g, points, px - a, py + b);
1904                 grid_face_set_dot(g, d, 1);
1905                 d = grid_get_dot(g, points, px - a - b, py + a + b);
1906                 grid_face_set_dot(g, d, 2);
1907                 d = grid_get_dot(g, points, px - 2*a - b, py + a);
1908                 grid_face_set_dot(g, d, 3);
1909             }
1910            
1911             /* Triangle below right */
1912             if ((x < width - 1) && (y < height - 1)) {
1913                 grid_face_add_new(g, 3);
1914                 d = grid_get_dot(g, points, px + a, py + b);
1915                 grid_face_set_dot(g, d, 0);
1916                 d = grid_get_dot(g, points, px + a + b, py + a + b);
1917                 grid_face_set_dot(g, d, 1);
1918                 d = grid_get_dot(g, points, px + a, py + 2*a + b);
1919                 grid_face_set_dot(g, d, 2);
1920             }
1921
1922             /* Triangle below left */
1923             if ((x > 0) && (y < height - 1)) {
1924                 grid_face_add_new(g, 3);
1925                 d = grid_get_dot(g, points, px - a, py + b);
1926                 grid_face_set_dot(g, d, 0);
1927                 d = grid_get_dot(g, points, px - a, py + 2*a + b);
1928                 grid_face_set_dot(g, d, 1);
1929                 d = grid_get_dot(g, points, px - a - b, py + a + b);
1930                 grid_face_set_dot(g, d, 2);
1931             }
1932         }
1933     }
1934
1935     freetree234(points);
1936     assert(g->num_faces <= max_faces);
1937     assert(g->num_dots <= max_dots);
1938
1939     grid_make_consistent(g);
1940     return g;
1941 }
1942
1943 #define OCTAGONAL_TILESIZE 40
1944 /* b/a approx sqrt(2) */
1945 #define OCTAGONAL_A 29
1946 #define OCTAGONAL_B 41
1947
1948 void grid_size_octagonal(int width, int height,
1949                           int *tilesize, int *xextent, int *yextent)
1950 {
1951     int a = OCTAGONAL_A;
1952     int b = OCTAGONAL_B;
1953
1954     *tilesize = OCTAGONAL_TILESIZE;
1955     *xextent = (2*a + b) * width;
1956     *yextent = (2*a + b) * height;
1957 }
1958
1959 grid *grid_new_octagonal(int width, int height, char *desc)
1960 {
1961     int x, y;
1962     int a = OCTAGONAL_A;
1963     int b = OCTAGONAL_B;
1964
1965     /* Upper bounds - don't have to be exact */
1966     int max_faces = 2 * width * height;
1967     int max_dots = 4 * (width + 1) * (height + 1);
1968
1969     tree234 *points;
1970
1971     grid *g = grid_empty();
1972     g->tilesize = OCTAGONAL_TILESIZE;
1973     g->faces = snewn(max_faces, grid_face);
1974     g->dots = snewn(max_dots, grid_dot);
1975
1976     points = newtree234(grid_point_cmp_fn);
1977
1978     for (y = 0; y < height; y++) {
1979         for (x = 0; x < width; x++) {
1980             grid_dot *d;
1981             /* cell position */
1982             int px = (2*a + b) * x;
1983             int py = (2*a + b) * y;
1984             /* octagon */
1985             grid_face_add_new(g, 8);
1986             d = grid_get_dot(g, points, px + a, py);
1987             grid_face_set_dot(g, d, 0);
1988             d = grid_get_dot(g, points, px + a + b, py);
1989             grid_face_set_dot(g, d, 1);
1990             d = grid_get_dot(g, points, px + 2*a + b, py + a);
1991             grid_face_set_dot(g, d, 2);
1992             d = grid_get_dot(g, points, px + 2*a + b, py + a + b);
1993             grid_face_set_dot(g, d, 3);
1994             d = grid_get_dot(g, points, px + a + b, py + 2*a + b);
1995             grid_face_set_dot(g, d, 4);
1996             d = grid_get_dot(g, points, px + a, py + 2*a + b);
1997             grid_face_set_dot(g, d, 5);
1998             d = grid_get_dot(g, points, px, py + a + b);
1999             grid_face_set_dot(g, d, 6);
2000             d = grid_get_dot(g, points, px, py + a);
2001             grid_face_set_dot(g, d, 7);
2002
2003             /* diamond */
2004             if ((x > 0) && (y > 0)) {
2005                 grid_face_add_new(g, 4);
2006                 d = grid_get_dot(g, points, px, py - a);
2007                 grid_face_set_dot(g, d, 0);
2008                 d = grid_get_dot(g, points, px + a, py);
2009                 grid_face_set_dot(g, d, 1);
2010                 d = grid_get_dot(g, points, px, py + a);
2011                 grid_face_set_dot(g, d, 2);
2012                 d = grid_get_dot(g, points, px - a, py);
2013                 grid_face_set_dot(g, d, 3);
2014             }
2015         }
2016     }
2017
2018     freetree234(points);
2019     assert(g->num_faces <= max_faces);
2020     assert(g->num_dots <= max_dots);
2021
2022     grid_make_consistent(g);
2023     return g;
2024 }
2025
2026 #define KITE_TILESIZE 40
2027 /* b/a approx sqrt(3) */
2028 #define KITE_A 15
2029 #define KITE_B 26
2030
2031 void grid_size_kites(int width, int height,
2032                      int *tilesize, int *xextent, int *yextent)
2033 {
2034     int a = KITE_A;
2035     int b = KITE_B;
2036
2037     *tilesize = KITE_TILESIZE;
2038     *xextent = 4*b * width + 2*b;
2039     *yextent = 6*a * (height-1) + 8*a;
2040 }
2041
2042 grid *grid_new_kites(int width, int height, char *desc)
2043 {
2044     int x, y;
2045     int a = KITE_A;
2046     int b = KITE_B;
2047
2048     /* Upper bounds - don't have to be exact */
2049     int max_faces = 6 * width * height;
2050     int max_dots = 6 * (width + 1) * (height + 1);
2051
2052     tree234 *points;
2053
2054     grid *g = grid_empty();
2055     g->tilesize = KITE_TILESIZE;
2056     g->faces = snewn(max_faces, grid_face);
2057     g->dots = snewn(max_dots, grid_dot);
2058
2059     points = newtree234(grid_point_cmp_fn);
2060
2061     for (y = 0; y < height; y++) {
2062         for (x = 0; x < width; x++) {
2063             grid_dot *d;
2064             /* position of order-6 dot */
2065             int px = 4*b * x;
2066             int py = 6*a * y;
2067             if (y % 2)
2068                 px += 2*b;
2069
2070             /* kite pointing up-left */
2071             grid_face_add_new(g, 4);
2072             d = grid_get_dot(g, points, px, py);
2073             grid_face_set_dot(g, d, 0);
2074             d = grid_get_dot(g, points, px + 2*b, py);
2075             grid_face_set_dot(g, d, 1);
2076             d = grid_get_dot(g, points, px + 2*b, py + 2*a);
2077             grid_face_set_dot(g, d, 2);
2078             d = grid_get_dot(g, points, px + b, py + 3*a);
2079             grid_face_set_dot(g, d, 3);
2080
2081             /* kite pointing up */
2082             grid_face_add_new(g, 4);
2083             d = grid_get_dot(g, points, px, py);
2084             grid_face_set_dot(g, d, 0);
2085             d = grid_get_dot(g, points, px + b, py + 3*a);
2086             grid_face_set_dot(g, d, 1);
2087             d = grid_get_dot(g, points, px, py + 4*a);
2088             grid_face_set_dot(g, d, 2);
2089             d = grid_get_dot(g, points, px - b, py + 3*a);
2090             grid_face_set_dot(g, d, 3);
2091
2092             /* kite pointing up-right */
2093             grid_face_add_new(g, 4);
2094             d = grid_get_dot(g, points, px, py);
2095             grid_face_set_dot(g, d, 0);
2096             d = grid_get_dot(g, points, px - b, py + 3*a);
2097             grid_face_set_dot(g, d, 1);
2098             d = grid_get_dot(g, points, px - 2*b, py + 2*a);
2099             grid_face_set_dot(g, d, 2);
2100             d = grid_get_dot(g, points, px - 2*b, py);
2101             grid_face_set_dot(g, d, 3);
2102
2103             /* kite pointing down-right */
2104             grid_face_add_new(g, 4);
2105             d = grid_get_dot(g, points, px, py);
2106             grid_face_set_dot(g, d, 0);
2107             d = grid_get_dot(g, points, px - 2*b, py);
2108             grid_face_set_dot(g, d, 1);
2109             d = grid_get_dot(g, points, px - 2*b, py - 2*a);
2110             grid_face_set_dot(g, d, 2);
2111             d = grid_get_dot(g, points, px - b, py - 3*a);
2112             grid_face_set_dot(g, d, 3);
2113
2114             /* kite pointing down */
2115             grid_face_add_new(g, 4);
2116             d = grid_get_dot(g, points, px, py);
2117             grid_face_set_dot(g, d, 0);
2118             d = grid_get_dot(g, points, px - b, py - 3*a);
2119             grid_face_set_dot(g, d, 1);
2120             d = grid_get_dot(g, points, px, py - 4*a);
2121             grid_face_set_dot(g, d, 2);
2122             d = grid_get_dot(g, points, px + b, py - 3*a);
2123             grid_face_set_dot(g, d, 3);
2124
2125             /* kite pointing down-left */
2126             grid_face_add_new(g, 4);
2127             d = grid_get_dot(g, points, px, py);
2128             grid_face_set_dot(g, d, 0);
2129             d = grid_get_dot(g, points, px + b, py - 3*a);
2130             grid_face_set_dot(g, d, 1);
2131             d = grid_get_dot(g, points, px + 2*b, py - 2*a);
2132             grid_face_set_dot(g, d, 2);
2133             d = grid_get_dot(g, points, px + 2*b, py);
2134             grid_face_set_dot(g, d, 3);
2135         }
2136     }
2137
2138     freetree234(points);
2139     assert(g->num_faces <= max_faces);
2140     assert(g->num_dots <= max_dots);
2141
2142     grid_make_consistent(g);
2143     return g;
2144 }
2145
2146 #define FLORET_TILESIZE 150
2147 /* -py/px is close to tan(30 - atan(sqrt(3)/9))
2148  * using py=26 makes everything lean to the left, rather than right
2149  */
2150 #define FLORET_PX 75
2151 #define FLORET_PY -26
2152
2153 void grid_size_floret(int width, int height,
2154                           int *tilesize, int *xextent, int *yextent)
2155 {
2156     int px = FLORET_PX, py = FLORET_PY;         /* |( 75, -26)| = 79.43 */
2157     int qx = 4*px/5, qy = -py*2;                /* |( 60,  52)| = 79.40 */
2158     int ry = qy-py;
2159     /* rx unused in determining grid size. */
2160
2161     *tilesize = FLORET_TILESIZE;
2162     *xextent = (6*px+3*qx)/2 * (width-1) + 4*qx + 2*px;
2163     *yextent = (5*qy-4*py) * (height-1) + 4*qy + 2*ry;
2164 }
2165
2166 grid *grid_new_floret(int width, int height, char *desc)
2167 {
2168     int x, y;
2169     /* Vectors for sides; weird numbers needed to keep puzzle aligned with window
2170      * -py/px is close to tan(30 - atan(sqrt(3)/9))
2171      * using py=26 makes everything lean to the left, rather than right
2172      */
2173     int px = FLORET_PX, py = FLORET_PY;         /* |( 75, -26)| = 79.43 */
2174     int qx = 4*px/5, qy = -py*2;                /* |( 60,  52)| = 79.40 */
2175     int rx = qx-px, ry = qy-py;                 /* |(-15,  78)| = 79.38 */
2176
2177     /* Upper bounds - don't have to be exact */
2178     int max_faces = 6 * width * height;
2179     int max_dots = 9 * (width + 1) * (height + 1);
2180
2181     tree234 *points;
2182
2183     grid *g = grid_empty();
2184     g->tilesize = FLORET_TILESIZE;
2185     g->faces = snewn(max_faces, grid_face);
2186     g->dots = snewn(max_dots, grid_dot);
2187
2188     points = newtree234(grid_point_cmp_fn);
2189
2190     /* generate pentagonal faces */
2191     for (y = 0; y < height; y++) {
2192         for (x = 0; x < width; x++) {
2193             grid_dot *d;
2194             /* face centre */
2195             int cx = (6*px+3*qx)/2 * x;
2196             int cy = (4*py-5*qy) * y;
2197             if (x % 2)
2198                 cy -= (4*py-5*qy)/2;
2199             else if (y && y == height-1)
2200                 continue; /* make better looking grids?  try 3x3 for instance */
2201
2202             grid_face_add_new(g, 5);
2203             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2204             d = grid_get_dot(g, points, cx+2*rx   , cy+2*ry   ); grid_face_set_dot(g, d, 1);
2205             d = grid_get_dot(g, points, cx+2*rx+qx, cy+2*ry+qy); grid_face_set_dot(g, d, 2);
2206             d = grid_get_dot(g, points, cx+2*qx+rx, cy+2*qy+ry); grid_face_set_dot(g, d, 3);
2207             d = grid_get_dot(g, points, cx+2*qx   , cy+2*qy   ); grid_face_set_dot(g, d, 4);
2208
2209             grid_face_add_new(g, 5);
2210             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2211             d = grid_get_dot(g, points, cx+2*qx   , cy+2*qy   ); grid_face_set_dot(g, d, 1);
2212             d = grid_get_dot(g, points, cx+2*qx+px, cy+2*qy+py); grid_face_set_dot(g, d, 2);
2213             d = grid_get_dot(g, points, cx+2*px+qx, cy+2*py+qy); grid_face_set_dot(g, d, 3);
2214             d = grid_get_dot(g, points, cx+2*px   , cy+2*py   ); grid_face_set_dot(g, d, 4);
2215
2216             grid_face_add_new(g, 5);
2217             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2218             d = grid_get_dot(g, points, cx+2*px   , cy+2*py   ); grid_face_set_dot(g, d, 1);
2219             d = grid_get_dot(g, points, cx+2*px-rx, cy+2*py-ry); grid_face_set_dot(g, d, 2);
2220             d = grid_get_dot(g, points, cx-2*rx+px, cy-2*ry+py); grid_face_set_dot(g, d, 3);
2221             d = grid_get_dot(g, points, cx-2*rx   , cy-2*ry   ); grid_face_set_dot(g, d, 4);
2222
2223             grid_face_add_new(g, 5);
2224             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2225             d = grid_get_dot(g, points, cx-2*rx   , cy-2*ry   ); grid_face_set_dot(g, d, 1);
2226             d = grid_get_dot(g, points, cx-2*rx-qx, cy-2*ry-qy); grid_face_set_dot(g, d, 2);
2227             d = grid_get_dot(g, points, cx-2*qx-rx, cy-2*qy-ry); grid_face_set_dot(g, d, 3);
2228             d = grid_get_dot(g, points, cx-2*qx   , cy-2*qy   ); grid_face_set_dot(g, d, 4);
2229
2230             grid_face_add_new(g, 5);
2231             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2232             d = grid_get_dot(g, points, cx-2*qx   , cy-2*qy   ); grid_face_set_dot(g, d, 1);
2233             d = grid_get_dot(g, points, cx-2*qx-px, cy-2*qy-py); grid_face_set_dot(g, d, 2);
2234             d = grid_get_dot(g, points, cx-2*px-qx, cy-2*py-qy); grid_face_set_dot(g, d, 3);
2235             d = grid_get_dot(g, points, cx-2*px   , cy-2*py   ); grid_face_set_dot(g, d, 4);
2236
2237             grid_face_add_new(g, 5);
2238             d = grid_get_dot(g, points, cx        , cy        ); grid_face_set_dot(g, d, 0);
2239             d = grid_get_dot(g, points, cx-2*px   , cy-2*py   ); grid_face_set_dot(g, d, 1);
2240             d = grid_get_dot(g, points, cx-2*px+rx, cy-2*py+ry); grid_face_set_dot(g, d, 2);
2241             d = grid_get_dot(g, points, cx+2*rx-px, cy+2*ry-py); grid_face_set_dot(g, d, 3);
2242             d = grid_get_dot(g, points, cx+2*rx   , cy+2*ry   ); grid_face_set_dot(g, d, 4);
2243         }
2244     }
2245
2246     freetree234(points);
2247     assert(g->num_faces <= max_faces);
2248     assert(g->num_dots <= max_dots);
2249
2250     grid_make_consistent(g);
2251     return g;
2252 }
2253
2254 /* DODEC_* are used for dodecagonal and great-dodecagonal grids. */
2255 #define DODEC_TILESIZE 26
2256 /* Vector for side of triangle - ratio is close to sqrt(3) */
2257 #define DODEC_A 15
2258 #define DODEC_B 26
2259
2260 void grid_size_dodecagonal(int width, int height,
2261                           int *tilesize, int *xextent, int *yextent)
2262 {
2263     int a = DODEC_A;
2264     int b = DODEC_B;
2265
2266     *tilesize = DODEC_TILESIZE;
2267     *xextent = (4*a + 2*b) * (width-1) + 3*(2*a + b);
2268     *yextent = (3*a + 2*b) * (height-1) + 2*(2*a + b);
2269 }
2270
2271 grid *grid_new_dodecagonal(int width, int height, char *desc)
2272 {
2273     int x, y;
2274     int a = DODEC_A;
2275     int b = DODEC_B;
2276
2277     /* Upper bounds - don't have to be exact */
2278     int max_faces = 3 * width * height;
2279     int max_dots = 14 * width * height;
2280
2281     tree234 *points;
2282
2283     grid *g = grid_empty();
2284     g->tilesize = DODEC_TILESIZE;
2285     g->faces = snewn(max_faces, grid_face);
2286     g->dots = snewn(max_dots, grid_dot);
2287
2288     points = newtree234(grid_point_cmp_fn);
2289
2290     for (y = 0; y < height; y++) {
2291         for (x = 0; x < width; x++) {
2292             grid_dot *d;
2293             /* centre of dodecagon */
2294             int px = (4*a + 2*b) * x;
2295             int py = (3*a + 2*b) * y;
2296             if (y % 2)
2297                 px += 2*a + b;
2298
2299             /* dodecagon */
2300             grid_face_add_new(g, 12);
2301             d = grid_get_dot(g, points, px + (  a    ), py - (2*a + b)); grid_face_set_dot(g, d, 0);
2302             d = grid_get_dot(g, points, px + (  a + b), py - (  a + b)); grid_face_set_dot(g, d, 1);
2303             d = grid_get_dot(g, points, px + (2*a + b), py - (  a    )); grid_face_set_dot(g, d, 2);
2304             d = grid_get_dot(g, points, px + (2*a + b), py + (  a    )); grid_face_set_dot(g, d, 3);
2305             d = grid_get_dot(g, points, px + (  a + b), py + (  a + b)); grid_face_set_dot(g, d, 4);
2306             d = grid_get_dot(g, points, px + (  a    ), py + (2*a + b)); grid_face_set_dot(g, d, 5);
2307             d = grid_get_dot(g, points, px - (  a    ), py + (2*a + b)); grid_face_set_dot(g, d, 6);
2308             d = grid_get_dot(g, points, px - (  a + b), py + (  a + b)); grid_face_set_dot(g, d, 7);
2309             d = grid_get_dot(g, points, px - (2*a + b), py + (  a    )); grid_face_set_dot(g, d, 8);
2310             d = grid_get_dot(g, points, px - (2*a + b), py - (  a    )); grid_face_set_dot(g, d, 9);
2311             d = grid_get_dot(g, points, px - (  a + b), py - (  a + b)); grid_face_set_dot(g, d, 10);
2312             d = grid_get_dot(g, points, px - (  a    ), py - (2*a + b)); grid_face_set_dot(g, d, 11);
2313
2314             /* triangle below dodecagon */
2315             if ((y < height - 1 && (x < width - 1 || !(y % 2)) && (x > 0 || (y % 2)))) {
2316                 grid_face_add_new(g, 3);
2317                 d = grid_get_dot(g, points, px + a, py + (2*a +   b)); grid_face_set_dot(g, d, 0);
2318                 d = grid_get_dot(g, points, px    , py + (2*a + 2*b)); grid_face_set_dot(g, d, 1);
2319                 d = grid_get_dot(g, points, px - a, py + (2*a +   b)); grid_face_set_dot(g, d, 2);
2320             }
2321
2322             /* triangle above dodecagon */
2323             if ((y && (x < width - 1 || !(y % 2)) && (x > 0 || (y % 2)))) {
2324                 grid_face_add_new(g, 3);
2325                 d = grid_get_dot(g, points, px - a, py - (2*a +   b)); grid_face_set_dot(g, d, 0);
2326                 d = grid_get_dot(g, points, px    , py - (2*a + 2*b)); grid_face_set_dot(g, d, 1);
2327                 d = grid_get_dot(g, points, px + a, py - (2*a +   b)); grid_face_set_dot(g, d, 2);
2328             }
2329         }
2330     }
2331
2332     freetree234(points);
2333     assert(g->num_faces <= max_faces);
2334     assert(g->num_dots <= max_dots);
2335
2336     grid_make_consistent(g);
2337     return g;
2338 }
2339
2340 void grid_size_greatdodecagonal(int width, int height,
2341                           int *tilesize, int *xextent, int *yextent)
2342 {
2343     int a = DODEC_A;
2344     int b = DODEC_B;
2345
2346     *tilesize = DODEC_TILESIZE;
2347     *xextent = (6*a + 2*b) * (width-1) + 2*(2*a + b) + 3*a + b;
2348     *yextent = (3*a + 3*b) * (height-1) + 2*(2*a + b);
2349 }
2350
2351 grid *grid_new_greatdodecagonal(int width, int height, char *desc)
2352 {
2353     int x, y;
2354     /* Vector for side of triangle - ratio is close to sqrt(3) */
2355     int a = DODEC_A;
2356     int b = DODEC_B;
2357
2358     /* Upper bounds - don't have to be exact */
2359     int max_faces = 30 * width * height;
2360     int max_dots = 200 * width * height;
2361
2362     tree234 *points;
2363
2364     grid *g = grid_empty();
2365     g->tilesize = DODEC_TILESIZE;
2366     g->faces = snewn(max_faces, grid_face);
2367     g->dots = snewn(max_dots, grid_dot);
2368
2369     points = newtree234(grid_point_cmp_fn);
2370
2371     for (y = 0; y < height; y++) {
2372         for (x = 0; x < width; x++) {
2373             grid_dot *d;
2374             /* centre of dodecagon */
2375             int px = (6*a + 2*b) * x;
2376             int py = (3*a + 3*b) * y;
2377             if (y % 2)
2378                 px += 3*a + b;
2379
2380             /* dodecagon */
2381             grid_face_add_new(g, 12);
2382             d = grid_get_dot(g, points, px + (  a    ), py - (2*a + b)); grid_face_set_dot(g, d, 0);
2383             d = grid_get_dot(g, points, px + (  a + b), py - (  a + b)); grid_face_set_dot(g, d, 1);
2384             d = grid_get_dot(g, points, px + (2*a + b), py - (  a    )); grid_face_set_dot(g, d, 2);
2385             d = grid_get_dot(g, points, px + (2*a + b), py + (  a    )); grid_face_set_dot(g, d, 3);
2386             d = grid_get_dot(g, points, px + (  a + b), py + (  a + b)); grid_face_set_dot(g, d, 4);
2387             d = grid_get_dot(g, points, px + (  a    ), py + (2*a + b)); grid_face_set_dot(g, d, 5);
2388             d = grid_get_dot(g, points, px - (  a    ), py + (2*a + b)); grid_face_set_dot(g, d, 6);
2389             d = grid_get_dot(g, points, px - (  a + b), py + (  a + b)); grid_face_set_dot(g, d, 7);
2390             d = grid_get_dot(g, points, px - (2*a + b), py + (  a    )); grid_face_set_dot(g, d, 8);
2391             d = grid_get_dot(g, points, px - (2*a + b), py - (  a    )); grid_face_set_dot(g, d, 9);
2392             d = grid_get_dot(g, points, px - (  a + b), py - (  a + b)); grid_face_set_dot(g, d, 10);
2393             d = grid_get_dot(g, points, px - (  a    ), py - (2*a + b)); grid_face_set_dot(g, d, 11);
2394
2395             /* hexagon below dodecagon */
2396             if (y < height - 1 && (x < width - 1 || !(y % 2)) && (x > 0 || (y % 2))) {
2397                 grid_face_add_new(g, 6);
2398                 d = grid_get_dot(g, points, px +   a, py + (2*a +   b)); grid_face_set_dot(g, d, 0);
2399                 d = grid_get_dot(g, points, px + 2*a, py + (2*a + 2*b)); grid_face_set_dot(g, d, 1);
2400                 d = grid_get_dot(g, points, px +   a, py + (2*a + 3*b)); grid_face_set_dot(g, d, 2);
2401                 d = grid_get_dot(g, points, px -   a, py + (2*a + 3*b)); grid_face_set_dot(g, d, 3);
2402                 d = grid_get_dot(g, points, px - 2*a, py + (2*a + 2*b)); grid_face_set_dot(g, d, 4);
2403                 d = grid_get_dot(g, points, px -   a, py + (2*a +   b)); grid_face_set_dot(g, d, 5);
2404             }
2405
2406             /* hexagon above dodecagon */
2407             if (y && (x < width - 1 || !(y % 2)) && (x > 0 || (y % 2))) {
2408                 grid_face_add_new(g, 6);
2409                 d = grid_get_dot(g, points, px -   a, py - (2*a +   b)); grid_face_set_dot(g, d, 0);
2410                 d = grid_get_dot(g, points, px - 2*a, py - (2*a + 2*b)); grid_face_set_dot(g, d, 1);
2411                 d = grid_get_dot(g, points, px -   a, py - (2*a + 3*b)); grid_face_set_dot(g, d, 2);
2412                 d = grid_get_dot(g, points, px +   a, py - (2*a + 3*b)); grid_face_set_dot(g, d, 3);
2413                 d = grid_get_dot(g, points, px + 2*a, py - (2*a + 2*b)); grid_face_set_dot(g, d, 4);
2414                 d = grid_get_dot(g, points, px +   a, py - (2*a +   b)); grid_face_set_dot(g, d, 5);
2415             }
2416
2417             /* square on right of dodecagon */
2418             if (x < width - 1) {
2419                 grid_face_add_new(g, 4);
2420                 d = grid_get_dot(g, points, px + 2*a + b, py - a); grid_face_set_dot(g, d, 0);
2421                 d = grid_get_dot(g, points, px + 4*a + b, py - a); grid_face_set_dot(g, d, 1);
2422                 d = grid_get_dot(g, points, px + 4*a + b, py + a); grid_face_set_dot(g, d, 2);
2423                 d = grid_get_dot(g, points, px + 2*a + b, py + a); grid_face_set_dot(g, d, 3);
2424             }
2425
2426             /* square on top right of dodecagon */
2427             if (y && (x < width - 1 || !(y % 2))) {
2428                 grid_face_add_new(g, 4);
2429                 d = grid_get_dot(g, points, px + (  a    ), py - (2*a +   b)); grid_face_set_dot(g, d, 0);
2430                 d = grid_get_dot(g, points, px + (2*a    ), py - (2*a + 2*b)); grid_face_set_dot(g, d, 1);
2431                 d = grid_get_dot(g, points, px + (2*a + b), py - (  a + 2*b)); grid_face_set_dot(g, d, 2);
2432                 d = grid_get_dot(g, points, px + (  a + b), py - (  a +   b)); grid_face_set_dot(g, d, 3);
2433             }
2434
2435             /* square on top left of dodecagon */
2436             if (y && (x || (y % 2))) {
2437                 grid_face_add_new(g, 4);
2438                 d = grid_get_dot(g, points, px - (  a + b), py - (  a +   b)); grid_face_set_dot(g, d, 0);
2439                 d = grid_get_dot(g, points, px - (2*a + b), py - (  a + 2*b)); grid_face_set_dot(g, d, 1);
2440                 d = grid_get_dot(g, points, px - (2*a    ), py - (2*a + 2*b)); grid_face_set_dot(g, d, 2);
2441                 d = grid_get_dot(g, points, px - (  a    ), py - (2*a +   b)); grid_face_set_dot(g, d, 3);
2442             }
2443         }
2444     }
2445
2446     freetree234(points);
2447     assert(g->num_faces <= max_faces);
2448     assert(g->num_dots <= max_dots);
2449
2450     grid_make_consistent(g);
2451     return g;
2452 }
2453
2454 typedef struct setface_ctx
2455 {
2456     int xmin, xmax, ymin, ymax;
2457     int aoff;
2458
2459     grid *g;
2460     tree234 *points;
2461 } setface_ctx;
2462
2463 double round(double r)
2464 {
2465     return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
2466 }
2467
2468 int set_faces(penrose_state *state, vector *vs, int n, int depth)
2469 {
2470     setface_ctx *sf_ctx = (setface_ctx *)state->ctx;
2471     int i;
2472     int xs[4], ys[4];
2473     double cosa = cos(sf_ctx->aoff * PI / 180.0);
2474     double sina = sin(sf_ctx->aoff * PI / 180.0);
2475
2476     if (depth < state->max_depth) return 0;
2477 #ifdef DEBUG_PENROSE
2478     if (n != 4) return 0; /* triangles are sent as debugging. */
2479 #endif
2480
2481     for (i = 0; i < n; i++) {
2482         double tx = v_x(vs, i), ty = v_y(vs, i);
2483
2484         xs[i] = (int)round( tx*cosa + ty*sina);
2485         ys[i] = (int)round(-tx*sina + ty*cosa);
2486
2487         if (xs[i] < sf_ctx->xmin || xs[i] > sf_ctx->xmax) return 0;
2488         if (ys[i] < sf_ctx->ymin || ys[i] > sf_ctx->ymax) return 0;
2489     }
2490
2491     grid_face_add_new(sf_ctx->g, n);
2492     debug(("penrose: new face l=%f gen=%d...",
2493            penrose_side_length(state->start_size, depth), depth));
2494     for (i = 0; i < n; i++) {
2495         grid_dot *d = grid_get_dot(sf_ctx->g, sf_ctx->points,
2496                                    xs[i], ys[i]);
2497         grid_face_set_dot(sf_ctx->g, d, i);
2498         debug((" ... dot 0x%x (%d,%d) (was %2.2f,%2.2f)",
2499                d, d->x, d->y, v_x(vs, i), v_y(vs, i)));
2500     }
2501
2502     return 0;
2503 }
2504
2505 #define PENROSE_TILESIZE 100
2506
2507 void grid_size_penrose(int width, int height,
2508                        int *tilesize, int *xextent, int *yextent)
2509 {
2510     int l = PENROSE_TILESIZE;
2511
2512     *tilesize = l;
2513     *xextent = l * width;
2514     *yextent = l * height;
2515 }
2516
2517 static char *grid_new_desc_penrose(grid_type type, int width, int height, random_state *rs)
2518 {
2519     int tilesize = PENROSE_TILESIZE, startsz, depth, xoff, yoff, aoff;
2520     double outer_radius;
2521     int inner_radius;
2522     char gd[255];
2523     int which = (type == GRID_PENROSE_P2 ? PENROSE_P2 : PENROSE_P3);
2524
2525     /* We want to produce a random bit of penrose tiling, so we calculate
2526      * a random offset (within the patch that penrose.c calculates for us)
2527      * and an angle (multiple of 36) to rotate the patch. */
2528
2529     penrose_calculate_size(which, tilesize, width, height,
2530                            &outer_radius, &startsz, &depth);
2531
2532     /* Calculate radius of (circumcircle of) patch, subtract from
2533      * radius calculated. */
2534     inner_radius = (int)(outer_radius - sqrt(width*width + height*height));
2535
2536     /* Pick a random offset (the easy way: choose within outer square,
2537      * discarding while it's outside the circle) */
2538     do {
2539         xoff = random_upto(rs, 2*inner_radius) - inner_radius;
2540         yoff = random_upto(rs, 2*inner_radius) - inner_radius;
2541     } while (sqrt(xoff*xoff+yoff*yoff) > inner_radius);
2542
2543     aoff = random_upto(rs, 360/36) * 36;
2544
2545     debug(("grid_desc: ts %d, %dx%d patch, orad %2.2f irad %d",
2546            tilesize, width, height, outer_radius, inner_radius));
2547     debug(("    -> xoff %d yoff %d aoff %d", xoff, yoff, aoff));
2548
2549     sprintf(gd, "G%d,%d,%d", xoff, yoff, aoff);
2550
2551     return dupstr(gd);
2552 }
2553
2554 static char *grid_validate_desc_penrose(grid_type type, int width, int height, char *desc)
2555 {
2556     int tilesize = PENROSE_TILESIZE, startsz, depth, xoff, yoff, aoff, inner_radius;
2557     double outer_radius;
2558     int which = (type == GRID_PENROSE_P2 ? PENROSE_P2 : PENROSE_P3);
2559
2560     if (!desc)
2561         return "Missing grid description string.";
2562
2563     penrose_calculate_size(which, tilesize, width, height,
2564                            &outer_radius, &startsz, &depth);
2565     inner_radius = (int)(outer_radius - sqrt(width*width + height*height));
2566
2567     if (sscanf(desc, "G%d,%d,%d", &xoff, &yoff, &aoff) != 3)
2568         return "Invalid format grid description string.";
2569
2570     if (sqrt(xoff*xoff + yoff*yoff) > inner_radius)
2571         return "Patch offset out of bounds.";
2572     if ((aoff % 36) != 0 || aoff < 0 || aoff >= 360)
2573         return "Angle offset out of bounds.";
2574
2575     return NULL;
2576 }
2577
2578 /*
2579  * We're asked for a grid of a particular size, and we generate enough
2580  * of the tiling so we can be sure to have enough random grid from which
2581  * to pick.
2582  */
2583
2584 static grid *grid_new_penrose(int width, int height, int which, char *desc)
2585 {
2586     int max_faces, max_dots, tilesize = PENROSE_TILESIZE;
2587     int xsz, ysz, xoff, yoff;
2588     double rradius;
2589
2590     tree234 *points;
2591     grid *g;
2592
2593     penrose_state ps;
2594     setface_ctx sf_ctx;
2595
2596     penrose_calculate_size(which, tilesize, width, height,
2597                            &rradius, &ps.start_size, &ps.max_depth);
2598
2599     debug(("penrose: w%d h%d, tile size %d, start size %d, depth %d",
2600            width, height, tilesize, ps.start_size, ps.max_depth));
2601
2602     ps.new_tile = set_faces;
2603     ps.ctx = &sf_ctx;
2604
2605     max_faces = (width*3) * (height*3); /* somewhat paranoid... */
2606     max_dots = max_faces * 4; /* ditto... */
2607
2608     g = grid_empty();
2609     g->tilesize = tilesize;
2610     g->faces = snewn(max_faces, grid_face);
2611     g->dots = snewn(max_dots, grid_dot);
2612
2613     points = newtree234(grid_point_cmp_fn);
2614
2615     memset(&sf_ctx, 0, sizeof(sf_ctx));
2616     sf_ctx.g = g;
2617     sf_ctx.points = points;
2618
2619     if (desc != NULL) {
2620         if (sscanf(desc, "G%d,%d,%d", &xoff, &yoff, &sf_ctx.aoff) != 3)
2621             assert(!"Invalid grid description.");
2622     } else {
2623         xoff = yoff = 0;
2624     }
2625
2626     xsz = width * tilesize;
2627     ysz = height * tilesize;
2628
2629     sf_ctx.xmin = xoff - xsz/2;
2630     sf_ctx.xmax = xoff + xsz/2;
2631     sf_ctx.ymin = yoff - ysz/2;
2632     sf_ctx.ymax = yoff + ysz/2;
2633
2634     debug(("penrose: centre (%f, %f) xsz %f ysz %f",
2635            0.0, 0.0, xsz, ysz));
2636     debug(("penrose: x range (%f --> %f), y range (%f --> %f)",
2637            sf_ctx.xmin, sf_ctx.xmax, sf_ctx.ymin, sf_ctx.ymax));
2638
2639     penrose(&ps, which);
2640
2641     freetree234(points);
2642     assert(g->num_faces <= max_faces);
2643     assert(g->num_dots <= max_dots);
2644
2645     debug(("penrose: %d faces total (equivalent to %d wide by %d high)",
2646            g->num_faces, g->num_faces/height, g->num_faces/width));
2647
2648     grid_trim_vigorously(g);
2649     grid_make_consistent(g);
2650
2651     /*
2652      * Centre the grid in its originally promised rectangle.
2653      */
2654     g->lowest_x -= ((sf_ctx.xmax - sf_ctx.xmin) -
2655                     (g->highest_x - g->lowest_x)) / 2;
2656     g->highest_x = g->lowest_x + (sf_ctx.xmax - sf_ctx.xmin);
2657     g->lowest_y -= ((sf_ctx.ymax - sf_ctx.ymin) -
2658                     (g->highest_y - g->lowest_y)) / 2;
2659     g->highest_y = g->lowest_y + (sf_ctx.ymax - sf_ctx.ymin);
2660
2661     return g;
2662 }
2663
2664 void grid_size_penrose_p2_kite(int width, int height,
2665                        int *tilesize, int *xextent, int *yextent)
2666 {
2667     grid_size_penrose(width, height, tilesize, xextent, yextent);
2668 }
2669
2670 void grid_size_penrose_p3_thick(int width, int height,
2671                        int *tilesize, int *xextent, int *yextent)
2672 {
2673     grid_size_penrose(width, height, tilesize, xextent, yextent);
2674 }
2675
2676 grid *grid_new_penrose_p2_kite(int width, int height, char *desc)
2677 {
2678     return grid_new_penrose(width, height, PENROSE_P2, desc);
2679 }
2680
2681 grid *grid_new_penrose_p3_thick(int width, int height, char *desc)
2682 {
2683     return grid_new_penrose(width, height, PENROSE_P3, desc);
2684 }
2685
2686 /* ----------- End of grid generators ------------- */
2687
2688 #define FNNEW(upper,lower) &grid_new_ ## lower,
2689 #define FNSZ(upper,lower) &grid_size_ ## lower,
2690
2691 static grid *(*(grid_news[]))(int, int, char*) = { GRIDGEN_LIST(FNNEW) };
2692 static void(*(grid_sizes[]))(int, int, int*, int*, int*) = { GRIDGEN_LIST(FNSZ) };
2693
2694 char *grid_new_desc(grid_type type, int width, int height, random_state *rs)
2695 {
2696     if (type != GRID_PENROSE_P2 && type != GRID_PENROSE_P3)
2697         return NULL;
2698
2699     return grid_new_desc_penrose(type, width, height, rs);
2700 }
2701
2702 char *grid_validate_desc(grid_type type, int width, int height, char *desc)
2703 {
2704     if (type != GRID_PENROSE_P2 && type != GRID_PENROSE_P3) {
2705         if (desc != NULL)
2706             return "Grid description strings not used with this grid type";
2707         return NULL;
2708     }
2709
2710     return grid_validate_desc_penrose(type, width, height, desc);
2711 }
2712
2713 grid *grid_new(grid_type type, int width, int height, char *desc)
2714 {
2715     char *err = grid_validate_desc(type, width, height, desc);
2716     if (err) assert(!"Invalid grid description.");
2717
2718     return grid_news[type](width, height, desc);
2719 }
2720
2721 void grid_compute_size(grid_type type, int width, int height,
2722                        int *tilesize, int *xextent, int *yextent)
2723 {
2724     grid_sizes[type](width, height, tilesize, xextent, yextent);
2725 }
2726
2727 /* ----------- End of grid helpers ------------- */
2728
2729 /* vim: set shiftwidth=4 tabstop=8: */