mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Apply the rotation in Penrose grid descriptions by rotating in the
4-vector representation, rather than mucking about with sines and cosines after grid generation. _Should_ make no difference in the generated grids (there's a theoretical risk of an unlucky rounding error just about managing to push some point in or out of bounds, but I think it's vanishingly small), but simplifies the coordinate- flattening procedure, and in particular increases its chance of getting vertical lines actually vertical. (Prior to this change, the game ID 10x10t12:G2554,-31,108_a3b12h0a212a3d102b2a23a2e3b01b0a2c2a0c0 was generating a not-quite-vertical edge at top left, in the Java port but not on Linux; I suspect differences in sin and cos as the cause of the discrepancy. With the rotation done like this, the points' x-coordinates are now computed without reference to their y-coordinates.) [originally from svn r9168]
This commit is contained in:
13
grid.c
13
grid.c
@ -2472,7 +2472,6 @@ static grid *grid_new_greatdodecagonal(int width, int height, char *desc)
|
|||||||
typedef struct setface_ctx
|
typedef struct setface_ctx
|
||||||
{
|
{
|
||||||
int xmin, xmax, ymin, ymax;
|
int xmin, xmax, ymin, ymax;
|
||||||
int aoff;
|
|
||||||
|
|
||||||
grid *g;
|
grid *g;
|
||||||
tree234 *points;
|
tree234 *points;
|
||||||
@ -2488,8 +2487,6 @@ static int set_faces(penrose_state *state, vector *vs, int n, int depth)
|
|||||||
setface_ctx *sf_ctx = (setface_ctx *)state->ctx;
|
setface_ctx *sf_ctx = (setface_ctx *)state->ctx;
|
||||||
int i;
|
int i;
|
||||||
int xs[4], ys[4];
|
int xs[4], ys[4];
|
||||||
double cosa = cos(sf_ctx->aoff * PI / 180.0);
|
|
||||||
double sina = sin(sf_ctx->aoff * PI / 180.0);
|
|
||||||
|
|
||||||
if (depth < state->max_depth) return 0;
|
if (depth < state->max_depth) return 0;
|
||||||
#ifdef DEBUG_PENROSE
|
#ifdef DEBUG_PENROSE
|
||||||
@ -2499,8 +2496,8 @@ static int set_faces(penrose_state *state, vector *vs, int n, int depth)
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
double tx = v_x(vs, i), ty = v_y(vs, i);
|
double tx = v_x(vs, i), ty = v_y(vs, i);
|
||||||
|
|
||||||
xs[i] = (int)round_int_nearest_away( tx*cosa + ty*sina);
|
xs[i] = (int)round_int_nearest_away(tx);
|
||||||
ys[i] = (int)round_int_nearest_away(-tx*sina + ty*cosa);
|
ys[i] = (int)round_int_nearest_away(ty);
|
||||||
|
|
||||||
if (xs[i] < sf_ctx->xmin || xs[i] > sf_ctx->xmax) return 0;
|
if (xs[i] < sf_ctx->xmin || xs[i] > sf_ctx->xmax) return 0;
|
||||||
if (ys[i] < sf_ctx->ymin || ys[i] > sf_ctx->ymax) return 0;
|
if (ys[i] < sf_ctx->ymin || ys[i] > sf_ctx->ymax) return 0;
|
||||||
@ -2602,7 +2599,7 @@ static char *grid_validate_desc_penrose(grid_type type, int width, int height, c
|
|||||||
static grid *grid_new_penrose(int width, int height, int which, char *desc)
|
static grid *grid_new_penrose(int width, int height, int which, char *desc)
|
||||||
{
|
{
|
||||||
int max_faces, max_dots, tilesize = PENROSE_TILESIZE;
|
int max_faces, max_dots, tilesize = PENROSE_TILESIZE;
|
||||||
int xsz, ysz, xoff, yoff;
|
int xsz, ysz, xoff, yoff, aoff;
|
||||||
double rradius;
|
double rradius;
|
||||||
|
|
||||||
tree234 *points;
|
tree234 *points;
|
||||||
@ -2635,7 +2632,7 @@ static grid *grid_new_penrose(int width, int height, int which, char *desc)
|
|||||||
sf_ctx.points = points;
|
sf_ctx.points = points;
|
||||||
|
|
||||||
if (desc != NULL) {
|
if (desc != NULL) {
|
||||||
if (sscanf(desc, "G%d,%d,%d", &xoff, &yoff, &sf_ctx.aoff) != 3)
|
if (sscanf(desc, "G%d,%d,%d", &xoff, &yoff, &aoff) != 3)
|
||||||
assert(!"Invalid grid description.");
|
assert(!"Invalid grid description.");
|
||||||
} else {
|
} else {
|
||||||
xoff = yoff = 0;
|
xoff = yoff = 0;
|
||||||
@ -2654,7 +2651,7 @@ static grid *grid_new_penrose(int width, int height, int which, char *desc)
|
|||||||
debug(("penrose: x range (%f --> %f), y range (%f --> %f)",
|
debug(("penrose: x range (%f --> %f), y range (%f --> %f)",
|
||||||
sf_ctx.xmin, sf_ctx.xmax, sf_ctx.ymin, sf_ctx.ymax));
|
sf_ctx.xmin, sf_ctx.xmax, sf_ctx.ymin, sf_ctx.ymax));
|
||||||
|
|
||||||
penrose(&ps, which);
|
penrose(&ps, which, aoff);
|
||||||
|
|
||||||
freetree234(points);
|
freetree234(points);
|
||||||
assert(g->num_faces <= max_faces);
|
assert(g->num_faces <= max_faces);
|
||||||
|
@ -434,7 +434,7 @@ void penrose_count_tiles(int depth, int *nlarge, int *nsmall)
|
|||||||
* (later mail: this is an overestimate by about 5%)
|
* (later mail: this is an overestimate by about 5%)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int penrose(penrose_state *state, int which)
|
int penrose(penrose_state *state, int which, int angle)
|
||||||
{
|
{
|
||||||
vector vo = v_origin();
|
vector vo = v_origin();
|
||||||
vector vb = v_origin();
|
vector vb = v_origin();
|
||||||
@ -444,6 +444,9 @@ int penrose(penrose_state *state, int which)
|
|||||||
|
|
||||||
vb.b = state->start_size;
|
vb.b = state->start_size;
|
||||||
|
|
||||||
|
vo = v_rotate(vo, angle);
|
||||||
|
vb = v_rotate(vb, angle);
|
||||||
|
|
||||||
if (which == PENROSE_P2)
|
if (which == PENROSE_P2)
|
||||||
return penrose_p2_large(state, 0, 1, vo, vb);
|
return penrose_p2_large(state, 0, 1, vo, vb);
|
||||||
else
|
else
|
||||||
|
@ -42,7 +42,7 @@ struct penrose_state {
|
|||||||
|
|
||||||
enum { PENROSE_P2, PENROSE_P3 };
|
enum { PENROSE_P2, PENROSE_P3 };
|
||||||
|
|
||||||
extern int penrose(penrose_state *state, int which);
|
extern int penrose(penrose_state *state, int which, int angle);
|
||||||
|
|
||||||
/* Returns the side-length of a penrose tile at recursion level
|
/* Returns the side-length of a penrose tile at recursion level
|
||||||
* gen, given a starting side length. */
|
* gen, given a starting side length. */
|
||||||
|
Reference in New Issue
Block a user