Chris_M_Thomasson

rgb color plotter, test

Jan 28th, 2019
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.44 KB | None | 0 0
  1. /*
  2.     A Simple 2d Plane For Hugh, with proper aspect ratios!
  3.     Color adder, single channel
  4.     By: Chris M. Thomasson
  5. *_____________________________________________________________*/
  6.  
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <complex.h>
  12. #include <tgmath.h>
  13. #include <stdbool.h>
  14.  
  15.  
  16. #define CT_WIDTH 1920
  17. #define CT_HEIGHT 1080
  18. #define CT_N 10000000
  19.  
  20.  
  21.  
  22. struct ct_rgb
  23. {
  24.     unsigned char r;
  25.     unsigned char g;
  26.     unsigned char b;
  27. };
  28.  
  29.  
  30. struct ct_canvas
  31. {
  32.     unsigned long width;
  33.     unsigned long height;
  34.     //unsigned char* buf;
  35.     struct ct_rgb* buf;
  36. };
  37.  
  38. bool
  39. ct_canvas_create(
  40.     struct ct_canvas* const self,
  41.     unsigned long width,
  42.     unsigned long height
  43. ){
  44.     size_t size = width * height * sizeof(*self->buf);
  45.  
  46.     self->buf = calloc(1, size);
  47.  
  48.     if (self->buf)
  49.     {
  50.         self->width = width;
  51.         self->height = height;
  52.  
  53.         return true;
  54.     }
  55.  
  56.     return false;
  57. }
  58.  
  59. void
  60. ct_canvas_destroy(
  61.     struct ct_canvas const* const self
  62. ){
  63.     free(self->buf);
  64. }
  65.  
  66. bool
  67. ct_canvas_save_ppm(
  68.     struct ct_canvas const* const self,
  69.     char const* fname
  70. ){
  71.     FILE* fout = fopen(fname, "wb");
  72.  
  73.     if (fout)
  74.     {
  75.         // P6 by Bart over on:
  76.         // https://groups.google.com/forum/#!original/comp.lang.c/4196m3Raggs/2moZ67o5EwAJ
  77.  
  78.         char const ppm_head[] =
  79.             "P6\n"
  80.             "# Chris M. Thomasson Simple 2d Plane ver:0.0.0.0 (pre-alpha)";
  81.  
  82.         fprintf(fout, "%s\n%lu %lu\n%u\n",
  83.                 ppm_head,
  84.                 self->width, self->height,
  85.                 255U);
  86.  
  87.         size_t size = self->width * self->height;
  88.  
  89.         for (size_t i = 0; i < size; ++i)
  90.         {
  91.             //unsigned int c = self->buf[i];
  92.             struct ct_rgb* c = self->buf + i;
  93.  
  94.             fprintf(fout, "%c%c%c", c->r, c->g, c->b);
  95.             //fprintf(fout, "%c%c%c", c, 0U, 0U);
  96.         }
  97.  
  98.         if (! fclose(fout))
  99.         {
  100.             return true;
  101.         }
  102.     }
  103.  
  104.     return false;
  105. }
  106.  
  107.  
  108.  
  109.  
  110. struct ct_axes
  111. {
  112.     double xmin;
  113.     double xmax;
  114.     double ymin;
  115.     double ymax;
  116. };
  117.  
  118. struct ct_axes
  119. ct_axes_from_point(
  120.     double complex z,
  121.     double radius
  122. ){
  123.     struct ct_axes axes = {
  124.         creal(z) - radius, creal(z) + radius,
  125.         cimag(z) - radius, cimag(z) + radius
  126.     };
  127.  
  128.     return axes;
  129. }
  130.  
  131.  
  132. struct ct_plane
  133. {
  134.     struct ct_axes axes;
  135.     double xstep;
  136.     double ystep;
  137. };
  138.  
  139.  
  140. void
  141. ct_plane_init(
  142.     struct ct_plane* const self,
  143.     struct ct_axes const* axes,
  144.     unsigned long width,
  145.     unsigned long height
  146. ){
  147.     self->axes = *axes;
  148.  
  149.     double awidth = self->axes.xmax - self->axes.xmin;
  150.     double aheight = self->axes.ymax - self->axes.ymin;
  151.  
  152.     assert(width > 0 && height > 0 && awidth > 0.0);
  153.  
  154.     double daspect = fabs((double)height / width);
  155.     double waspect = fabs(aheight / awidth);
  156.  
  157.     if (daspect > waspect)
  158.     {
  159.         double excess = aheight * (daspect / waspect - 1.0);
  160.         self->axes.ymax += excess / 2.0;
  161.         self->axes.ymin -= excess / 2.0;
  162.     }
  163.  
  164.     else if (daspect < waspect)
  165.     {
  166.         double excess = awidth * (waspect / daspect - 1.0);
  167.         self->axes.xmax += excess / 2.0;
  168.         self->axes.xmin -= excess / 2.0;
  169.     }
  170.  
  171.     self->xstep = (self->axes.xmax - self->axes.xmin) / width;
  172.     self->ystep = (self->axes.ymax - self->axes.ymin) / height;
  173. }
  174.  
  175.  
  176.  
  177. struct ct_plot
  178. {
  179.     struct ct_plane plane;
  180.     struct ct_canvas* canvas;
  181. };
  182.  
  183.  
  184. void
  185. ct_plot_init(
  186.     struct ct_plot* const self,
  187.     struct ct_axes const* axes,
  188.     struct ct_canvas* canvas
  189. ){
  190.     ct_plane_init(&self->plane, axes, canvas->width - 1, canvas->height - 1);
  191.     self->canvas = canvas;
  192. }
  193.  
  194.  
  195. bool
  196. ct_plot_add(
  197.     struct ct_plot* const self,
  198.     double complex z,
  199.     struct ct_rgb const* color
  200. ){
  201.     long x = (creal(z) - self->plane.axes.xmin) / self->plane.xstep;
  202.     long y = (self->plane.axes.ymax - cimag(z)) / self->plane.ystep;
  203.  
  204.     if (x > -1 && x < (long)self->canvas->width &&
  205.         y > -1 && y < (long)self->canvas->height)
  206.     {
  207.         // Now, we can convert to index.
  208.         size_t i = x + y * self->canvas->width;
  209.  
  210.         assert(i < self->canvas->height * self->canvas->width);
  211.  
  212.         struct ct_rgb exist = self->canvas->buf[i];
  213.  
  214.         exist.r += 1;
  215.  
  216.         self->canvas->buf[i] = exist;
  217.         return true;
  218.     }
  219.  
  220.     return true;
  221. }
  222.  
  223.  
  224. bool
  225. ct_plot_point(
  226.     struct ct_plot* const self,
  227.     double complex z,
  228.     struct ct_rgb const* color
  229. ){
  230.     long x = (creal(z) - self->plane.axes.xmin) / self->plane.xstep;
  231.     long y = (self->plane.axes.ymax - cimag(z)) / self->plane.ystep;
  232.  
  233.     if (x > -1 && x < (long)self->canvas->width &&
  234.         y > -1 && y < (long)self->canvas->height)
  235.     {
  236.         // Now, we can convert to index.
  237.         size_t i = x + y * self->canvas->width;
  238.  
  239.         assert(i < self->canvas->height * self->canvas->width);
  240.  
  241.         self->canvas->buf[i] = *color;
  242.         return true;
  243.     }
  244.  
  245.     return false;
  246. }
  247.  
  248.  
  249.  
  250. // Compute the fractal
  251. void
  252. ct_ifs(
  253.     struct ct_plot* const plot,
  254.     unsigned long n
  255. ){
  256.     // 2 sets
  257.     /*
  258.     double complex jp[] = {
  259.         .5 + 0 * I,
  260.         -5.5 + 0 * I
  261.     };
  262.     */
  263.  
  264.     double complex jp[] = {
  265.         0 + 1 * I,
  266.         0 + -1 * I
  267.     };
  268.  
  269.     double complex z = 0+0*I;
  270.     double complex c = 0+0*I;
  271.  
  272.     for (unsigned long i = 0; i < n; ++i)
  273.     {
  274.         double rn0 = rand() / (RAND_MAX - .0);
  275.         double rn1 = rand() / (RAND_MAX - .0);
  276.  
  277.         if (rn0 > .5)
  278.         {
  279.             c = jp[0];
  280.         }
  281.  
  282.         else
  283.         {
  284.             c = jp[1];
  285.         }
  286.  
  287.  
  288.         double complex d = z - c;
  289.         double complex root = csqrt(d);
  290.  
  291.         z = root;
  292.  
  293.         if (rn1 > .5)
  294.         {
  295.             z = -root;
  296.         }
  297.  
  298.         struct ct_rgb rgb = { 255, 0, 0 };
  299.  
  300.        // ct_plot_point(plot, z, &rgb);
  301.        // ct_plot_point(plot, root, &rgb);
  302.         ct_plot_add(plot, z, &rgb);
  303.         ct_plot_add(plot, root, &rgb);
  304.  
  305.         if (! (i % (n / 3)))
  306.         {
  307.             printf("rendering: %lu of %lu\r", i + 1, n);
  308.         }
  309.     }
  310.  
  311.     printf("rendering: %lu of %lu\n", n, n);
  312. }
  313.  
  314.  
  315.  
  316.  
  317.  
  318. // slow, so what for now... ;^)
  319. void ct_circle(
  320.     struct ct_plot* const plot,
  321.     double complex c,
  322.     double radius,
  323.     unsigned int n
  324. ){
  325.     double abase = 6.2831853071 / n;
  326.  
  327.     for (unsigned int i = 0; i < n; ++i)
  328.     {
  329.         double angle = abase * i;
  330.  
  331.         double complex z =
  332.             (creal(c) + cos(angle) * radius) +
  333.             (cimag(c) + sin(angle) * radius) * I;
  334.  
  335.         struct ct_rgb rgb = { 255, 255, 255 };
  336.  
  337.         ct_plot_point(plot, z, &rgb);
  338.     }
  339. }
  340.  
  341.  
  342. int main(void)
  343. {
  344.     struct ct_canvas canvas;
  345.  
  346.     if (ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT))
  347.     {
  348.         double complex plane_origin = 0+0*I;
  349.         double plane_radius = 2.0;
  350.  
  351.         struct ct_axes axes = ct_axes_from_point(plane_origin, plane_radius);
  352.  
  353.         struct ct_plot plot;
  354.         ct_plot_init(&plot, &axes, &canvas);
  355.  
  356.  
  357.         ct_ifs(&plot, CT_N);
  358.  
  359.         // Our unit circle
  360.         ct_circle(&plot, 0+0*I, 1.0, 2048);
  361.         ct_circle(&plot, 2+0*I, 2.0, 2048);
  362.         ct_circle(&plot, -2+0*I, 2.0, 2048);
  363.         ct_circle(&plot, 0+2*I, 2.0, 2048);
  364.         ct_circle(&plot, 0-2*I, 2.0, 2048);
  365.  
  366.         ct_canvas_save_ppm(&canvas, "ct_plane.ppm");
  367.  
  368.         ct_canvas_destroy(&canvas);
  369.  
  370.         return EXIT_SUCCESS;
  371.     }
  372.  
  373.     return EXIT_FAILURE;
  374. }
Advertisement
Add Comment
Please, Sign In to add comment