A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 86 lines 3.2 kB view raw
1#ifndef PUZZLES_PENROSE_H 2#define PUZZLES_PENROSE_H 3 4struct PenrosePatchParams { 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}; 25 26#ifndef PENROSE_ENUM_DEFINED 27#define PENROSE_ENUM_DEFINED 28enum { PENROSE_P2, PENROSE_P3 }; 29#endif 30 31bool penrose_valid_letter(char c, int which); 32 33/* 34 * Fill in PenrosePatchParams with a randomly selected set of 35 * coordinates, in enough detail to generate a patch of tiling filling 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). 49 * 50 * (In case it's useful, the y scale factor sin(pi/5)/2 is an 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. 56 */ 57void penrose_tiling_randomise(struct PenrosePatchParams *params, int which, 58 int w, int h, random_state *rs); 59 60/* 61 * Validate a PenrosePatchParams to ensure it contains no illegal 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); 67 68/* 69 * Generate the actual set of Penrose tiles from a PenrosePatchParams, 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); 79 80#define PENROSE_NVERTICES 4 81 82void penrose_tiling_generate( 83 const struct PenrosePatchParams *params, int w, int h, 84 penrose_tile_callback_fn cb, void *cbctx); 85 86#endif