hat-test: alternative data output mode to write Python.

This mode emits a sequence of calls to an imaginary Python function.
Should be useful to anyone wanting to post-process the tiling in any
way.
This commit is contained in:
Simon Tatham
2023-03-28 20:35:03 +01:00
parent 828c7da785
commit 827051dafe

118
hat.c
View File

@ -1256,43 +1256,83 @@ static inline void psbbox_add(psbbox *bbox, pspoint p)
bbox->started = true; bbox->started = true;
} }
static void header(psbbox *bbox) typedef enum OutFmt { OF_POSTSCRIPT, OF_PYTHON } OutFmt;
{
float xext = bbox->tr.x - bbox->bl.x, yext = bbox->tr.y - bbox->bl.y;
float ext = (xext > yext ? xext : yext);
float scale = 500 / ext;
float ox = 287 - scale * (bbox->bl.x + bbox->tr.x) / 2;
float oy = 421 - scale * (bbox->bl.y + bbox->tr.y) / 2;
printf("%%!PS-Adobe-2.0\n%%%%Creator: hat-test from Simon Tatham's " typedef struct drawctx {
"Portable Puzzle Collection\n%%%%Pages: 1\n" OutFmt outfmt;
"%%%%BoundingBox: %f %f %f %f\n" psbbox *bbox;
"%%%%EndComments\n%%%%Page: 1 1\n", } drawctx;
ox + scale * bbox->bl.x - 20, oy + scale * bbox->bl.y - 20,
ox + scale * bbox->tr.x + 20, oy + scale * bbox->tr.y + 20);
printf("%f %f translate %f dup scale\n", ox, oy, scale);
printf("%f setlinewidth\n", scale * 0.03);
printf("0 setgray 1 setlinejoin 1 setlinecap\n");
}
static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords) static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
{ {
psbbox *bbox = (psbbox *)vctx; drawctx *ctx = (drawctx *)vctx;
pspoint p; pspoint p;
size_t i; size_t i;
for (i = 0; i < 14; i++) { for (i = 0; i < 14; i++) {
p.x = coords[2*i] * 1.5; p.x = coords[2*i] * 1.5;
p.y = coords[2*i+1] * sqrt(0.75); p.y = coords[2*i+1] * sqrt(0.75);
psbbox_add(bbox, p); psbbox_add(ctx->bbox, p);
}
}
static void header(drawctx *ctx)
{
switch (ctx->outfmt) {
case OF_POSTSCRIPT: {
float xext = ctx->bbox->tr.x - ctx->bbox->bl.x;
float yext = ctx->bbox->tr.y - ctx->bbox->bl.y;
float ext = (xext > yext ? xext : yext);
float scale = 500 / ext;
float ox = 287 - scale * (ctx->bbox->bl.x + ctx->bbox->tr.x) / 2;
float oy = 421 - scale * (ctx->bbox->bl.y + ctx->bbox->tr.y) / 2;
printf("%%!PS-Adobe-2.0\n%%%%Creator: hat-test from Simon Tatham's "
"Portable Puzzle Collection\n%%%%Pages: 1\n"
"%%%%BoundingBox: %f %f %f %f\n"
"%%%%EndComments\n%%%%Page: 1 1\n",
ox + scale * ctx->bbox->bl.x - 20,
oy + scale * ctx->bbox->bl.y - 20,
ox + scale * ctx->bbox->tr.x + 20,
oy + scale * ctx->bbox->tr.y + 20);
printf("%f %f translate %f dup scale\n", ox, oy, scale);
printf("%f setlinewidth\n", scale * 0.03);
printf("0 setgray 1 setlinejoin 1 setlinecap\n");
break;
}
default:
break;
} }
} }
static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords) static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
{ {
drawctx *ctx = (drawctx *)vctx;
pspoint p; pspoint p;
size_t i; size_t i;
int orientation;
/*
* Determine an index for the hat's orientation, based on the axis
* of symmetry of its kite #0.
*/
{
int dx = kite0.outer.x - kite0.centre.x;
int dy = kite0.outer.y - kite0.centre.y;
orientation = 0;
while (dx < 0 || dy < 0) {
int newdx = dx + dy;
int newdy = -dx;
dx = newdx;
dy = newdy;
orientation++;
assert(orientation < 6);
}
}
switch (ctx->outfmt) {
case OF_POSTSCRIPT: {
const char *colour; const char *colour;
printf("newpath"); printf("newpath");
@ -1312,13 +1352,31 @@ static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
} }
printf(" %s fill grestore", colour); printf(" %s fill grestore", colour);
printf(" stroke\n"); printf(" stroke\n");
break;
}
case OF_PYTHON: {
printf("hat('%c', %d, %d, [", "HTPF"[hc->c[2].type], hc->c[1].index,
orientation);
for (i = 0; i < 14; i++)
printf("%s(%d,%d)", i ? ", " : "", coords[2*i], coords[2*i+1]);
printf("])\n");
break;
}
}
} }
static void trailer(void) static void trailer(drawctx *dctx)
{ {
switch (dctx->outfmt) {
case OF_POSTSCRIPT: {
printf("showpage\n"); printf("showpage\n");
printf("%%%%Trailer\n"); printf("%%%%Trailer\n");
printf("%%%%EOF\n"); printf("%%%%EOF\n");
break;
}
default:
break;
}
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -1331,6 +1389,9 @@ int main(int argc, char **argv)
int w = 10, h = 10; int w = 10, h = 10;
int argpos = 0; int argpos = 0;
size_t i; size_t i;
drawctx dctx[1];
dctx->outfmt = OF_POSTSCRIPT;
while (--argc > 0) { while (--argc > 0) {
const char *arg = *++argv; const char *arg = *++argv;
@ -1340,6 +1401,8 @@ int main(int argc, char **argv)
return 0; return 0;
} else if (!strcmp(arg, "--test")) { } else if (!strcmp(arg, "--test")) {
return unit_tests() ? 0 : 1; return unit_tests() ? 0 : 1;
} else if (!strcmp(arg, "--python")) {
dctx->outfmt = OF_PYTHON;
} else if (arg[0] == '-') { } else if (arg[0] == '-') {
fprintf(stderr, "unrecognised option '%s'\n", arg); fprintf(stderr, "unrecognised option '%s'\n", arg);
return 1; return 1;
@ -1364,42 +1427,43 @@ int main(int argc, char **argv)
init_coords_random(ctx, rs); init_coords_random(ctx, rs);
bbox->started = false; bbox->started = false;
dctx->bbox = bbox;
first_kite(s, w, h); first_kite(s, w, h);
coords[s->curr_index] = initial_coords(ctx); coords[s->curr_index] = initial_coords(ctx);
maybe_report_hat(w, h, *s->curr, coords[s->curr_index], maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
bbox_add_hat, bbox); bbox_add_hat, dctx);
while (next_kite(s)) { while (next_kite(s)) {
hc_free(coords[s->curr_index]); hc_free(coords[s->curr_index]);
coords[s->curr_index] = step_coords( coords[s->curr_index] = step_coords(
ctx, coords[s->last_index], s->last_step); ctx, coords[s->last_index], s->last_step);
maybe_report_hat(w, h, *s->curr, coords[s->curr_index], maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
bbox_add_hat, bbox); bbox_add_hat, dctx);
} }
for (i = 0; i < lenof(coords); i++) { for (i = 0; i < lenof(coords); i++) {
hc_free(coords[i]); hc_free(coords[i]);
coords[i] = NULL; coords[i] = NULL;
} }
header(bbox); header(dctx);
first_kite(s, w, h); first_kite(s, w, h);
coords[s->curr_index] = initial_coords(ctx); coords[s->curr_index] = initial_coords(ctx);
maybe_report_hat(w, h, *s->curr, coords[s->curr_index], maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
draw_hat, NULL); draw_hat, dctx);
while (next_kite(s)) { while (next_kite(s)) {
hc_free(coords[s->curr_index]); hc_free(coords[s->curr_index]);
coords[s->curr_index] = step_coords( coords[s->curr_index] = step_coords(
ctx, coords[s->last_index], s->last_step); ctx, coords[s->last_index], s->last_step);
maybe_report_hat(w, h, *s->curr, coords[s->curr_index], maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
draw_hat, NULL); draw_hat, dctx);
} }
for (i = 0; i < lenof(coords); i++) { for (i = 0; i < lenof(coords); i++) {
hc_free(coords[i]); hc_free(coords[i]);
coords[i] = NULL; coords[i] = NULL;
} }
trailer(); trailer(dctx);
cleanup_coords(ctx); cleanup_coords(ctx);