Chris_M_Thomasson

RIFC Experimental Plotter by Chris M. Thomasson

Jun 29th, 2017
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.84 KB | None | 0 0
  1. /* Experimental Fractal Data Storage by:
  2.    Chris M. Thomasson
  3.    Copyright 2017
  4. ________________________________________________________*/
  5.  
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <assert.h>
  10. #include <complex.h>
  11. #include <tgmath.h>
  12. #include <stdbool.h>
  13.  
  14.  
  15. #define CT_PI2 6.283185307179586476925286766559
  16.  
  17. // Our loading threshold, 32 nits
  18. #define CT_LOAD_MAX 32
  19.  
  20. // Our epsilon for error
  21. #define CT_FIND_EPS 0.00000001
  22.  
  23. typedef double ct_real;
  24. typedef double complex ct_complex;
  25.  
  26.  
  27. /* Generic Plotter by Chris M. Thomasson
  28. ________________________________________________________*/
  29. struct ct_axes
  30. {
  31.     ct_real xmin;
  32.     ct_real xmax;
  33.     ct_real ymin;
  34.     ct_real ymax;
  35. };
  36.  
  37. struct ct_axes
  38. ct_axes_get(
  39.     ct_complex center,
  40.     ct_real diameter
  41. ){
  42.     ct_real radius = diameter / 2;
  43.  
  44.     struct ct_axes axes = {
  45.         creal(center) - radius,
  46.         creal(center) + radius,
  47.         cimag(center) - radius,
  48.         cimag(center) + radius,
  49.     };
  50.  
  51.     return axes;
  52. }
  53.  
  54.  
  55. struct ct_canvas_color
  56. {
  57.     unsigned char red;
  58.     unsigned char green;
  59.     unsigned char blue;
  60.     unsigned char alpha;
  61. };
  62.  
  63.  
  64. struct ct_canvas
  65. {
  66.     unsigned long width;
  67.     unsigned long height;
  68.     struct ct_canvas_color* buf;
  69. };
  70.  
  71. bool
  72. ct_canvas_create(
  73.     struct ct_canvas* const self,
  74.     unsigned long width,
  75.     unsigned long height
  76. ){
  77.     size_t size = width * height * sizeof(*self->buf);
  78.  
  79.     self->buf = calloc(1, size);
  80.  
  81.     if (self->buf)
  82.     {
  83.         self->width = width;
  84.         self->height = height;
  85.  
  86.         return true;
  87.     }
  88.  
  89.     return false;
  90. }
  91.  
  92. void
  93. ct_canvas_destroy(
  94.     struct ct_canvas const* const self
  95. ){
  96.     free(self->buf);
  97. }
  98.  
  99. bool
  100. ct_canvas_save_ppm(
  101.      struct ct_canvas const* const self,
  102.      char const* fname
  103. ){
  104.     FILE* fout = fopen(fname, "w");
  105.  
  106.     if (fout)
  107.     {
  108.         char const ppm_head[] =
  109.          "P3\n"
  110.          "# Chris M. Thomasson RIFC Cipher Renderer ver:0.0.0.0 (pre-alpha)";
  111.  
  112.         fprintf(fout, "%s\n%lu %lu\n%u\n",
  113.              ppm_head,
  114.              self->width, self->height,
  115.              255U);
  116.  
  117.         size_t size = self->width * self->height;
  118.  
  119.         for (size_t i = 0; i < size; ++i)
  120.         {
  121.             struct ct_canvas_color c = self->buf[i];
  122.             fprintf(fout, "%u %u %u  ", c.red, c.green, c.blue);
  123.         }
  124.  
  125.         if (! fclose(fout))
  126.         {
  127.             return true;
  128.         }
  129.     }
  130.  
  131.     return false;
  132. }
  133.  
  134.  
  135. struct ct_plane
  136. {
  137.     struct ct_axes axes;
  138.     struct ct_canvas* canvas;
  139. };
  140.  
  141. struct ct_pixel
  142. {
  143.     size_t x;
  144.     size_t y;
  145. };
  146.  
  147.  
  148. struct ct_pixel
  149. ct_plane_project(
  150.     struct ct_plane const* const self,
  151.     ct_complex c
  152. ){
  153.      ct_real awidth = self->axes.xmax - self->axes.xmin;
  154.      ct_real aheight = self->axes.ymax - self->axes.ymin;
  155.  
  156.      ct_real xstep = awidth / (self->canvas->width - 1.0);
  157.      ct_real ystep = aheight / (self->canvas->height - 1.0);
  158.  
  159.      struct ct_pixel pixel = {
  160.          (creal(c) - self->axes.xmin) / xstep,
  161.          (self->axes.ymax - cimag(c)) / ystep
  162.      };
  163.  
  164.      return pixel;
  165. }
  166.  
  167. bool
  168. ct_plane_plot(
  169.     struct ct_plane* const self,
  170.     ct_complex c,
  171.     struct ct_canvas_color color
  172. ){
  173.      struct ct_pixel pixel = ct_plane_project(self, c);
  174.  
  175.      if (pixel.x < self->canvas->width && pixel.y < self->canvas->height)
  176.      {
  177.          size_t cp = pixel.x + pixel.y * self->canvas->height;
  178.  
  179.          if (cp < self->canvas->height * self->canvas->width)
  180.          {
  181.              self->canvas->buf[cp] = color;
  182.              return true;
  183.          }
  184.      }
  185.  
  186.      return false;
  187. }
  188.  
  189.  
  190. /* RIFC (original) by Chris M. Thomasson
  191. ________________________________________________________*/
  192. ct_complex
  193. ct_root(
  194.     ct_complex const z,
  195.     long p,
  196.     unsigned long r
  197. ){
  198.     ct_real radius = pow(fabs(z), 1.0 / p);
  199.     ct_real angle_base = carg(z) / p;
  200.     ct_real angle_step = CT_PI2 / p;
  201.     ct_real angle = angle_base + angle_step * r;
  202.     ct_complex root = cos(angle) * radius + sin(angle) * radius * I;
  203.  
  204.     return root;
  205. }
  206.  
  207. // Stores a number v using a base
  208. ct_complex
  209. ct_store(
  210.     struct ct_plane* const plane,
  211.     ct_complex z,
  212.     ct_complex c,
  213.     unsigned long v,
  214.     long p
  215. ){
  216.     unsigned long b = abs(p);
  217.  
  218.     /*
  219.     printf("ct_store:((%lf%+lfi), (%lf%+lfi), %lu, %ld)\n"
  220.            "_______________________________\n",
  221.            creal(z), cimag(z), creal(c), cimag(c), v, p);
  222. */
  223.     while (v)
  224.     {
  225.         // Gain the base
  226.         unsigned long d = v / b;
  227.         unsigned long r = v - d * b;
  228.  
  229.         // Compute the proper root for the base
  230.         z = ct_root(z - c, p, r);
  231.  
  232.         //printf("(%lf%+lfi):%lu\n", creal(z), cimag(z), r);
  233.  
  234.         struct ct_canvas_color color = {
  235.             v & 0x000000FF,
  236.             (v & 0x0000FF00) >> 8,
  237.             //(v & 0x00FF0000) >> 16,
  238.             255,
  239.             0
  240.         };
  241.  
  242.         // Plot the point
  243.         ct_plane_plot(plane, z, color);
  244.  
  245.         v = d;
  246.     }
  247.  
  248.    // printf("result:(%lf%+lfi)\n", creal(z), cimag(z));
  249.     //printf("_______________________________\n\n");
  250.  
  251.     return z;
  252. }
  253.  
  254. // Loads a number at a base from z.
  255. ct_complex
  256. ct_load(
  257.     ct_complex z0,
  258.     ct_complex z,
  259.     ct_complex c,
  260.     unsigned long* pv,
  261.     long p
  262. ){
  263.     unsigned long v = 0;
  264.     unsigned long b = abs(p);
  265.  
  266.     /*
  267.     printf("ct_load:((%lf%+lfi), (%lf%+lfi), %p, %ld)\n"
  268.        "_______________________________\n",
  269.        creal(z), cimag(z), creal(c), cimag(c), (void*)pv, p);
  270.        */
  271.  
  272.     for (unsigned long i = 0; i < CT_LOAD_MAX; ++i)
  273.     {
  274.         // Check for termination condition
  275.         ct_real d = fabs(z - z0);
  276.         if (d < CT_FIND_EPS) break;
  277.  
  278.         // Raise z to the power and add c
  279.         ct_complex zn = pow(z, p) + c;
  280.  
  281.         ct_complex r = 0 + 0 * I;
  282.         unsigned long ii = 0;
  283.  
  284.         // Search for the stored root
  285.         for (ii = 0; ii < b; ++ii)
  286.         {
  287.             r = ct_root(zn - c, p, ii);
  288.             ct_real d = fabs(z - r);
  289.             if (d < CT_FIND_EPS) break;
  290.         }
  291.  
  292.         // Recreate the number
  293.         v = b * v + ii;
  294.  
  295.         //printf("(%lf%+lfi):%lu\n", creal(z), cimag(z), ii);
  296.  
  297.         // Set the next iteration
  298.         z = zn;
  299.     }
  300.  
  301.     *pv = v;
  302.  
  303.     /*
  304.     printf("result:((%lf%+lfi), %lu)\n", creal(z), cimag(z), *pv);
  305.     printf("_______________________________\n\n");
  306.     */
  307.  
  308.     return z;
  309. }
  310.  
  311.  
  312. // Canvas width and height
  313. #define CT_WIDTH 512
  314. #define CT_HEIGHT CT_WIDTH
  315.  
  316. int main(void)
  317. {
  318.     struct ct_canvas canvas;
  319.  
  320.     bool status = ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT);
  321.     assert(status);
  322.  
  323.     // Setup our plotting axes and plane
  324.     ct_complex center = 0 + 0 * I;
  325.     ct_real zoom_diameter = 3.5;
  326.     struct ct_axes axes = ct_axes_get(center, zoom_diameter);
  327.     struct ct_plane plane = { axes, &canvas };
  328.  
  329.     // Our initial conditions
  330.     ct_complex z = -1+.0;
  331.     ct_complex c = -.75+.06*I;
  332.  
  333.     // Power of -2
  334.     long p = 2;
  335.     unsigned long e = 0;
  336.  
  337.     // Try to store/load values 0 through vmax-1
  338.     unsigned long vmax = 65536;
  339.     for (unsigned long v = 0; v < vmax; ++v)
  340.     {
  341.         // Store the data!
  342.         ct_complex z0 = z;
  343.         z = ct_store(&plane, z, c, v, p);
  344.  
  345.         // Load the data and check for errors!
  346.         unsigned long lv = 0;
  347.         ct_load(z0, z, c, &lv, p);
  348.  
  349.         if (lv != v)
  350.         {
  351.             //printf("ERROR: %lu != %lu       \n", lv, v);
  352.             e += 1;
  353.         }
  354.  
  355.         // Display progress
  356.         if (! (v % (vmax / 2048)))
  357.         {
  358.             printf("plotted:%lu of %lu, error: %lu\r", v, vmax, e);
  359.         }
  360.     }
  361.  
  362.     printf("Plotting Complete:%lu of %lu, %lu errors\r", vmax, vmax, e);
  363.  
  364.     status = ct_canvas_save_ppm(&canvas, "ct_cipher_rifc.ppm");
  365.     assert(status);
  366.     printf("\ncreated: ct_cipher_rifc.ppm\n");
  367.     ct_canvas_destroy(&canvas);
  368.  
  369.     return 0;
  370. }
Advertisement
Add Comment
Please, Sign In to add comment