aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hat.c150
1 files changed, 59 insertions, 91 deletions
diff --git a/hat.c b/hat.c
index b6d2448..8872670 100644
--- a/hat.c
+++ b/hat.c
@@ -959,9 +959,14 @@ const char *hat_tiling_params_invalid(const struct HatPatchParams *hp)
* kites inside the rectangle, so its kite #0 will certainly be caught
* by this iteration.)
*/
+
+typedef void (*internal_hat_callback_fn)(void *ctx, Kite kite0, HatCoords *hc,
+ int *coords);
+
static void maybe_report_hat(int w, int h, Kite kite, HatCoords *hc,
- hat_tile_callback_fn cb, void *cbctx)
+ internal_hat_callback_fn cb, void *cbctx)
{
+ Kite kite0;
Point vertices[14];
size_t i, j;
bool reversed = false;
@@ -970,6 +975,7 @@ static void maybe_report_hat(int w, int h, Kite kite, HatCoords *hc,
/* Only iterate from kite #0 of a hat */
if (hc->c[0].index != 0)
return;
+ kite0 = kite;
/*
* Identify reflected hats: they are always hat #3 of an H
@@ -1032,7 +1038,17 @@ static void maybe_report_hat(int w, int h, Kite kite, HatCoords *hc,
coords[2*i+1] = y;
}
- cb(cbctx, 14, coords);
+ cb(cbctx, kite0, hc, coords);
+}
+
+struct internal_ctx {
+ hat_tile_callback_fn external_cb;
+ void *external_cbctx;
+};
+static void report_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
+{
+ struct internal_ctx *ctx = (struct internal_ctx *)vctx;
+ ctx->external_cb(ctx->external_cbctx, 14, coords);
}
/*
@@ -1045,6 +1061,10 @@ void hat_tiling_generate(const struct HatPatchParams *hp, int w, int h,
HatCoords *coords[KE_NKEEP];
KiteEnum s[1];
size_t i;
+ struct internal_ctx report_hat_ctx[1];
+
+ report_hat_ctx->external_cb = cb;
+ report_hat_ctx->external_cbctx = cbctx;
init_coords_params(ctx, hp);
for (i = 0; i < lenof(coords); i++)
@@ -1052,13 +1072,15 @@ void hat_tiling_generate(const struct HatPatchParams *hp, int w, int h,
first_kite(s, w, h);
coords[s->curr_index] = initial_coords(ctx);
- maybe_report_hat(w, h, *s->curr, coords[s->curr_index], cb, cbctx);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ report_hat, report_hat_ctx);
while (next_kite(s)) {
hc_free(coords[s->curr_index]);
coords[s->curr_index] = step_coords(
ctx, coords[s->last_index], s->last_step);
- maybe_report_hat(w, h, *s->curr, coords[s->curr_index], cb, cbctx);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ report_hat, report_hat_ctx);
}
cleanup_coords(ctx);
@@ -1216,12 +1238,6 @@ typedef struct pspoint {
float x, y;
} pspoint;
-static inline pspoint pscoords(Point p)
-{
- pspoint q = { p.x + p.y / 2.0F, p.y * sqrt(0.75) };
- return q;
-}
-
typedef struct psbbox {
bool started;
pspoint bl, tr;
@@ -1256,84 +1272,46 @@ static void header(psbbox *bbox)
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", 0.1);
- printf("/thick { %f setlinewidth } def\n", 0.7);
+ printf("%f setlinewidth\n", scale * 0.03);
printf("0 setgray 1 setlinejoin 1 setlinecap\n");
}
-static void bbox_add_kite(Kite k, psbbox *bbox)
-{
- pspoint p[4];
- size_t i;
-
- p[0] = pscoords(k.centre);
- p[1] = pscoords(k.left);
- p[2] = pscoords(k.outer);
- p[3] = pscoords(k.right);
-
- for (i = 0; i < 4; i++)
- psbbox_add(bbox, p[i]);
-}
-
-static void fill_kite(Kite k, HatCoords *hc)
+static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
{
- pspoint p[4];
+ psbbox *bbox = (psbbox *)vctx;
+ pspoint p;
size_t i;
- p[0] = pscoords(k.centre);
- p[1] = pscoords(k.left);
- p[2] = pscoords(k.outer);
- p[3] = pscoords(k.right);
-
- printf("newpath");
- for (i = 0; i < 4; i++)
- printf(" %f %f %s", p[i].x, p[i].y, i ? "lineto" : "moveto");
- printf(" closepath gsave");
- if (hc) {
- const char *colour = "0 setgray";
- if (hc->c[2].type == TT_H) {
- colour = (hc->c[1].index == 3 ? "0 0.5 0.8 setrgbcolor" :
- "0.6 0.8 1 setrgbcolor");
- } else if (hc->c[2].type == TT_F) {
- colour = "0.7 setgray";
- } else {
- colour = "1 setgray";
- }
- printf(" %s fill grestore\n", colour);
+ for (i = 0; i < 14; i++) {
+ p.x = coords[2*i] * 1.5;
+ p.y = coords[2*i+1] * sqrt(0.75);
+ psbbox_add(bbox, p);
}
}
-static void stroke_kite(Kite k, HatCoords *hc)
+static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
{
- pspoint p[4];
+ pspoint p;
size_t i;
-
- p[0] = pscoords(k.centre);
- p[1] = pscoords(k.left);
- p[2] = pscoords(k.outer);
- p[3] = pscoords(k.right);
+ const char *colour;
printf("newpath");
- for (i = 0; i < 4; i++)
- printf(" %f %f %s", p[i].x, p[i].y, i ? "lineto" : "moveto");
- printf(" closepath");
- printf(" stroke\n");
-
- if (hc->c[2].type == TT_H && hc->c[1].index == 3) {
- pspoint t = p[1]; p[1] = p[3]; p[3] = t;
+ for (i = 0; i < 14; i++) {
+ p.x = coords[2*i] * 1.5;
+ p.y = coords[2*i+1] * sqrt(0.75);
+ printf(" %f %f %s", p.x, p.y, i ? "lineto" : "moveto");
}
- #define LINE(a,b) printf("gsave newpath %f %f moveto %f %f lineto thick " \
- "stroke grestore\n", p[a].x, p[a].y, p[b].x, p[b].y)
- switch (hc->c[0].index) {
- case 0: LINE(1, 2); LINE(2, 3); LINE(3, 0); break;
- case 1: LINE(0, 1); break;
- case 2: LINE(0, 1); break;
- case 3: LINE(2, 3); LINE(3, 0); break;
- case 4: LINE(0, 1); LINE(1, 2); break;
- case 6: LINE(1, 2); LINE(2, 3); break;
- case 7: LINE(1, 2); LINE(2, 3); LINE(3, 0); break;
+ printf(" closepath gsave");
+ if (hc->c[2].type == TT_H) {
+ colour = (hc->c[1].index == 3 ? "0 0.5 0.8 setrgbcolor" :
+ "0.6 0.8 1 setrgbcolor");
+ } else if (hc->c[2].type == TT_F) {
+ colour = "0.7 setgray";
+ } else {
+ colour = "1 setgray";
}
- #undef LINE
+ printf(" %s fill grestore", colour);
+ printf(" stroke\n");
}
static void trailer(void)
@@ -1366,12 +1344,14 @@ int main(int argc, char **argv)
first_kite(s, w, h);
coords[s->curr_index] = initial_coords(ctx);
- bbox_add_kite(*s->curr, bbox);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ bbox_add_hat, bbox);
while (next_kite(s)) {
hc_free(coords[s->curr_index]);
coords[s->curr_index] = step_coords(
ctx, coords[s->last_index], s->last_step);
- bbox_add_kite(*s->curr, bbox);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ bbox_add_hat, bbox);
}
for (i = 0; i < lenof(coords); i++) {
hc_free(coords[i]);
@@ -1382,26 +1362,14 @@ int main(int argc, char **argv)
first_kite(s, w, h);
coords[s->curr_index] = initial_coords(ctx);
- fill_kite(*s->curr, coords[s->curr_index]);
- while (next_kite(s)) {
- hc_free(coords[s->curr_index]);
- coords[s->curr_index] = step_coords(
- ctx, coords[s->last_index], s->last_step);
- fill_kite(*s->curr, coords[s->curr_index]);
- }
- for (i = 0; i < lenof(coords); i++) {
- hc_free(coords[i]);
- coords[i] = NULL;
- }
-
- first_kite(s, w, h);
- coords[s->curr_index] = initial_coords(ctx);
- stroke_kite(*s->curr, coords[s->curr_index]);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ draw_hat, NULL);
while (next_kite(s)) {
hc_free(coords[s->curr_index]);
coords[s->curr_index] = step_coords(
ctx, coords[s->last_index], s->last_step);
- stroke_kite(*s->curr, coords[s->curr_index]);
+ maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
+ draw_hat, NULL);
}
for (i = 0; i < lenof(coords); i++) {
hc_free(coords[i]);