summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/penrose.h
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/src/penrose.h')
-rw-r--r--apps/plugins/puzzles/src/penrose.h119
1 files changed, 73 insertions, 46 deletions
diff --git a/apps/plugins/puzzles/src/penrose.h b/apps/plugins/puzzles/src/penrose.h
index ba5ae16f2c..e6e927d618 100644
--- a/apps/plugins/puzzles/src/penrose.h
+++ b/apps/plugins/puzzles/src/penrose.h
@@ -1,59 +1,86 @@
1/* penrose.h 1#ifndef PUZZLES_PENROSE_H
2 * 2#define PUZZLES_PENROSE_H
3 * Penrose tiling functions.
4 *
5 * Provides an interface with which to generate Penrose tilings
6 * by recursive subdivision of an initial tile of choice (one of the
7 * four sets of two pairs kite/dart, or thin/thick rhombus).
8 *
9 * You supply a callback function and a context pointer, which is
10 * called with each tile in turn: you choose how many times to recurse.
11 */
12 3
13#ifndef _PENROSE_H 4struct PenrosePatchParams {
14#define _PENROSE_H 5 /*
6 * A patch of Penrose tiling is identified by giving
7 *
8 * - the coordinates of the starting triangle, using a
9 * combinatorial coordinate system
10 *
11 * - which vertex of that triangle is at the centre point of the
12 * tiling
13 *
14 * - the orientation of the triangle's base edge, as a number
15 * from 0 to 9, measured in tenths of a turn
16 *
17 * Coordinates are a sequence of letters. For a P2 tiling all
18 * letters are from the set {A,B,U,V}; for P3, {C,D,X,Y}.
19 */
20 unsigned start_vertex;
21 int orientation;
22 size_t ncoords;
23 char *coords;
24};
15 25
16#ifndef PHI 26#ifndef PENROSE_ENUM_DEFINED
17#define PHI 1.6180339887 27#define PENROSE_ENUM_DEFINED
28enum { PENROSE_P2, PENROSE_P3 };
18#endif 29#endif
19 30
20typedef struct vector vector; 31bool penrose_valid_letter(char c, int which);
21
22double v_x(vector *vs, int i);
23double v_y(vector *vs, int i);
24 32
25typedef struct penrose_state penrose_state; 33/*
26 34 * Fill in PenrosePatchParams with a randomly selected set of
27/* Return non-zero to clip the tree here (i.e. not recurse 35 * coordinates, in enough detail to generate a patch of tiling filling
28 * below this tile). 36 * a w x h area.
37 *
38 * Units of measurement: the tiling will be oriented such that
39 * horizontal tile edges are possible (and therefore vertical ones are
40 * not). Therefore, all x-coordinates will be rational linear
41 * combinations of 1 and sqrt(5), and all y-coordinates will be
42 * sin(pi/5) times such a rational linear combination. By scaling up
43 * appropriately we can turn those rational combinations into
44 * _integer_ combinations, so we do. Therefore, w is measured in units
45 * of 1/4, and h is measured in units of sin(pi/5)/2, on a scale where
46 * a length of 1 corresponds to the legs of the acute isosceles
47 * triangles in the tiling (hence, the long edges of P2 kites and
48 * darts, or all edges of P3 rhombs).
29 * 49 *
30 * Parameters are state, vector array, npoints, depth. 50 * (In case it's useful, the y scale factor sin(pi/5)/2 is an
31 * ctx is inside state. 51 * algebraic number. Its minimal polynomial is 256x^4 - 80x^2 + 5.)
52 *
53 * The 'coords' field of the structure will be filled in with a new
54 * dynamically allocated array. Any previous pointer in that field
55 * will be overwritten.
32 */ 56 */
33typedef int (*tile_callback)(penrose_state *, vector *, int, int); 57void penrose_tiling_randomise(struct PenrosePatchParams *params, int which,
34 58 int w, int h, random_state *rs);
35struct penrose_state {
36 int start_size; /* initial side length */
37 int max_depth; /* Recursion depth */
38
39 tile_callback new_tile;
40 void *ctx; /* for callback */
41};
42 59
43enum { PENROSE_P2, PENROSE_P3 }; 60/*
44 61 * Validate a PenrosePatchParams to ensure it contains no illegal
45extern int penrose(penrose_state *state, int which, int angle); 62 * coordinates. Returns NULL if it's acceptable, or an error string if
63 * not.
64 */
65const char *penrose_tiling_params_invalid(
66 const struct PenrosePatchParams *params, int which);
46 67
47/* Returns the side-length of a penrose tile at recursion level 68/*
48 * gen, given a starting side length. */ 69 * Generate the actual set of Penrose tiles from a PenrosePatchParams,
49extern double penrose_side_length(double start_size, int depth); 70 * passing each one to a callback. The callback receives the vertices
71 * of each point, in the form of an array of 4*4 integers. Each vertex
72 * is represented by four consecutive integers in this array, with the
73 * first two giving the x coordinate and the last two the y
74 * coordinate. Each pair of integers a,b represent a single coordinate
75 * whose value is a + b*sqrt(5). The units of measurement for x and y
76 * are as described above.
77 */
78typedef void (*penrose_tile_callback_fn)(void *ctx, const int *coords);
50 79
51/* Returns the count of each type of tile at a given recursion depth. */ 80#define PENROSE_NVERTICES 4
52extern void penrose_count_tiles(int gen, int *nlarge, int *nsmall);
53 81
54/* Calculate start size and recursion depth required to produce a 82void penrose_tiling_generate(
55 * width-by-height sized patch of penrose tiles with the given tilesize */ 83 const struct PenrosePatchParams *params, int w, int h,
56extern void penrose_calculate_size(int which, int tilesize, int w, int h, 84 penrose_tile_callback_fn cb, void *cbctx);
57 double *required_radius, int *start_size, int *depth);
58 85
59#endif 86#endif