/* Generate the Fibonacci word as a texture. * * The Fibonacci word is the morphic word generated by the limit of * the L-system * b where b → a and a → ab * but here we are going to use a finite recursion limit. * * The first few iterations of this L-system play out as follows: * * b * a * ab * aba * abaab * abaababa * abaababaabaab * abaababaabaababaababa * abaababaabaababaababaabaababaabaab * abaababaabaababaababaabaababaabaababaababaabaababaababa * * With recursion limit N, the L-system generates fib(N) letters. In * this case a couple million is more than enough. fib(34) = 5702887 * (by some definition) but just to be safe we use 100. * * Our generate_a and generate_b functions return 0 on failure, as * does our append function. This permits the 100 levels of stack to * unwind in linear time rather than exponential time. * * The resulting texture may be technically nonrepeating but it sure * looks repetitive. */ #include "ppmp6.h" enum { ww = 512, hh = 512 }; ppm_p6_color image[hh][ww]; typedef struct { ppm_p6_color *outp; int remaining_pixels; ppm_p6_color palette[256]; } output; static inline int append(output *out, char color) { if (!out->remaining_pixels) return 0; *out->outp++ = out->palette[(int)(unsigned char)color]; out->remaining_pixels--; return 1; } static inline int generate_a(output *out, int maxdepth); static inline int generate_b(output *out, int maxdepth) { if (maxdepth) { return generate_a(out, maxdepth-1); } return append(out, 'b'); } static inline int generate_a(output *out, int maxdepth) { if (maxdepth) { return generate_a(out, maxdepth-1) && generate_b(out, maxdepth-1); } return append(out, 'a'); } int main(int argc, char **argv) { output out = {image[0], ww*hh}; ppm_p6_color white = { r: 1, g: 1, b: 1 }; out.palette[(int)'a'] = white; generate_b(&out, 100); ppm_p6_output_image(image[0], ww, hh); return 0; }