Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #140290

Simple 2d C99 fractal plotter...

From "Chris M. Thomasson" <ahh_f_it@crap.nothing>
Newsgroups comp.lang.c
Subject Simple 2d C99 fractal plotter...
Date 2019-01-25 14:24 -0800
Organization A noiseless patient Spider
Message-ID <q2g2bo$deg$1@dont-email.me> (permalink)

Show all headers | View raw


Just wondering, when you get some free time, if you can perhaps run the 
my experimental plotter code that generates a PPM called "ct_plane.ppm". 
And if you can see a fractal in the resulting rendering. Here is my C99 
code:

https://pastebin.com/raw/322XAnsT
(raw text, pure C99: no ads!)

It should just compile with GCC, and run like a charm. It has proper 
aspect ratios so one can use any dimensions they want.

Can you notice anything wrong with the code below:

Btw, Hugh is one of my fractal friends... :^)
___________________________
/*
     A Simple 2d Plane For Hugh, with proper aspect ratios!
     By: Chris M. Thomasson
*_____________________________________________________________*/


#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <complex.h>
#include <tgmath.h>
#include <stdbool.h>


#define CT_WIDTH 1920
#define CT_HEIGHT 1080
#define CT_N 5000000


struct ct_canvas
{
     unsigned long width;
     unsigned long height;
     unsigned char* buf;
};

bool
ct_canvas_create(
     struct ct_canvas* const self,
     unsigned long width,
     unsigned long height
){
     size_t size = width * height;

     self->buf = calloc(1, size);

     if (self->buf)
     {
         self->width = width;
         self->height = height;

         return true;
     }

     return false;
}

void
ct_canvas_destroy(
     struct ct_canvas const* const self
){
     free(self->buf);
}

bool
ct_canvas_save_ppm(
     struct ct_canvas const* const self,
     char const* fname
){
     FILE* fout = fopen(fname, "w");

     if (fout)
     {
         char const ppm_head[] =
             "P3\n"
             "# Chris M. Thomasson Simple 2d Plane ver:0.0.0.0 (pre-alpha)";

         fprintf(fout, "%s\n%lu %lu\n%u\n",
                 ppm_head,
                 self->width, self->height,
                 255U);

         size_t size = self->width * self->height;

         for (size_t i = 0; i < size; ++i)
         {
             unsigned int c = self->buf[i];
             fprintf(fout, "%u %u %u  ", c, 0U, 0U);
         }

         if (! fclose(fout))
         {
             return true;
         }
     }

     return false;
}




struct ct_axes
{
     double xmin;
     double xmax;
     double ymin;
     double ymax;
};

struct ct_axes
ct_axes_from_point(
     double complex z,
     double radius
){
     struct ct_axes axes = {
         creal(z) - radius, creal(z) + radius,
         cimag(z) - radius, cimag(z) + radius
     };

     return axes;
}


struct ct_plane
{
     struct ct_axes axes;
     double xstep;
     double ystep;
};


void
ct_plane_init(
     struct ct_plane* const self,
     struct ct_axes const* axes,
     unsigned long width,
     unsigned long height
){
     self->axes = *axes;

     double awidth = self->axes.xmax - self->axes.xmin;
     double aheight = self->axes.ymax - self->axes.ymin;

     assert(width > 0 && height > 0 && awidth > 0.0);

     double daspect = fabs((double)height / width);
     double waspect = fabs(aheight / awidth);

     if (daspect > waspect)
     {
         double excess = aheight * (daspect / waspect - 1.0);
         self->axes.ymax += excess / 2.0;
         self->axes.ymin -= excess / 2.0;
     }

     else if (daspect < waspect)
     {
         double excess = awidth * (waspect / daspect - 1.0);
         self->axes.xmax += excess / 2.0;
         self->axes.xmin -= excess / 2.0;
     }

     self->xstep = (self->axes.xmax - self->axes.xmin) / width;
     self->ystep = (self->axes.ymax - self->axes.ymin) / height;
}



struct ct_plot
{
     struct ct_plane plane;
     struct ct_canvas* canvas;
};


void
ct_plot_init(
     struct ct_plot* const self,
     struct ct_axes const* axes,
     struct ct_canvas* canvas
){
     ct_plane_init(&self->plane, axes, canvas->width - 1, canvas->height 
- 1);
     self->canvas = canvas;
}


bool
ct_plot_point(
     struct ct_plot* const self,
     double complex z,
     unsigned char color
){
     long x = (creal(z) - self->plane.axes.xmin) / self->plane.xstep;
     long y = (self->plane.axes.ymax - cimag(z)) / self->plane.ystep;

     if (x > -1 && x < (long)self->canvas->width &&
         y > -1 && y < (long)self->canvas->height)
     {
         // Now, we can convert to index.
         size_t i = x + y * self->canvas->width;

         assert(i < self->canvas->height * self->canvas->width);

         self->canvas->buf[i] = color;
         return true;
     }

     return false;
}



// Compute the fractal
void
ct_ifs(
     struct ct_plot* const plot,
     unsigned long n
){
     // 2 sets
     double complex jp[] = {
         .5 + 0 * I,
         -5.5 + I*.0
     };

     double complex z = 0+0*I;
     double complex c = 0+0*I;

     for (unsigned long i = 0; i < n; ++i)
     {
         double rn0 = rand() / (RAND_MAX - .0);
         double rn1 = rand() / (RAND_MAX - .0);

         if (rn0 > .5)
         {
             c = jp[0];
         }

         else
         {
             c = jp[1];
         }


         double complex d = z - c;
         double complex root = csqrt(d);

         z = root;

         if (rn1 > .5)
         {
             z = -root;
         }

          ct_plot_point(plot, z, 255);
          ct_plot_point(plot, root, 255);

         if (! (i % 256))
         {
             printf("rendering: %lu of %lu\r", i + 1, n);
         }
     }

     printf("rendering: %lu of %lu\n", n, n);
}





// slow, so what for now... ;^)
void ct_circle(
     struct ct_plot* const plot,
     double complex c,
     double radius,
     unsigned int n
){
     double abase = 6.2831853071 / n;

     for (unsigned int i = 0; i < n; ++i)
     {
         double angle = abase * i;

         double complex z =
             (creal(c) + cos(angle) * radius) +
             (cimag(c) + sin(angle) * radius) * I;

         ct_plot_point(plot, z, 255);
     }
}


int main(void)
{
     struct ct_canvas canvas;

     if (ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT))
     {
         double complex plane_origin = 0+0*I;
         double plane_radius = 2.0;

         struct ct_axes axes = ct_axes_from_point(plane_origin, 
plane_radius);

         struct ct_plot plot;
         ct_plot_init(&plot, &axes, &canvas);


         ct_ifs(&plot, CT_N);

         // Our unit circle
         ct_circle(&plot, 0+0*I, 1.0, 2048);
         ct_circle(&plot, 2+0*I, 2.0, 2048);
         ct_circle(&plot, -2+0*I, 2.0, 2048);
         ct_circle(&plot, 0+2*I, 2.0, 2048);
         ct_circle(&plot, 0-2*I, 2.0, 2048);

         ct_canvas_save_ppm(&canvas, "ct_plane.ppm");

         ct_canvas_destroy(&canvas);

         return EXIT_SUCCESS;
     }

     return EXIT_FAILURE;
}
___________________________

Back to comp.lang.c | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

Simple 2d C99 fractal plotter... "Chris M. Thomasson" <ahh_f_it@crap.nothing> - 2019-01-25 14:24 -0800
  Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson " <ahh_f_it@crap.nothing> - 2019-01-25 15:11 -0800
  Re: Simple 2d C99 fractal plotter... Eli the Bearded <*@eli.users.panix.com> - 2019-01-25 23:50 +0000
    Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <ahh_f_it@crap.nothing> - 2019-01-25 16:33 -0800
    Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 00:45 +0000
      Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson " <ahh_f_it@crap.nothing> - 2019-01-25 16:55 -0800
        Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 00:59 +0000
      Re: Simple 2d C99 fractal plotter... Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-01-26 20:29 +0000
        Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 21:37 +0000
          Re: Simple 2d C99 fractal plotter... Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-01-27 12:11 +0000
            Re: Simple 2d C99 fractal plotter... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-27 13:40 +0000
  Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 00:57 +0000
    Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <ahh_f_it@crap.nothing> - 2019-01-27 15:37 -0800
  Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 12:35 +0000
    Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-01-27 13:20 +0100
      Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-27 14:13 +0000
        Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-01-27 16:36 +0100
          Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <ahh_f_it@crap.nothing> - 2019-01-27 14:28 -0800
            Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-27 23:53 +0000
          Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-01-29 13:11 -0800
            Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-29 22:23 +0000
              Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-02-04 15:30 -0800
                Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-02-05 01:26 +0000
                Re: Simple 2d C99 fractal plotter... Ian Collins <ian-news@hotmail.com> - 2019-02-05 16:14 +1300
                Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-02-05 11:38 +0100
                Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-02-05 11:14 +0000
                Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-02-05 14:35 +0100
                Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-02-05 15:06 +0000
                Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-02-05 17:02 +0100
                Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-02-05 19:07 +0000
                Re: Simple 2d C99 fractal plotter... Ian Collins <ian-news@hotmail.com> - 2019-02-06 08:12 +1300
                Re: Simple 2d C99 fractal plotter... Keith Thompson <kst-u@mib.org> - 2019-02-05 12:49 -0800
                Re: Simple 2d C99 fractal plotter... David Brown <david.brown@hesbynett.no> - 2019-02-05 22:39 +0100
        Re: Simple 2d C99 fractal plotter... Keith Thompson <kst-u@mib.org> - 2019-01-27 13:09 -0800
  Re: Simple 2d C99 fractal plotter... Bart <bc@freeuk.com> - 2019-01-26 18:53 +0000
    Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <ahh_f_it@crap.nothing> - 2019-01-26 18:21 -0800
  Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-01-28 22:20 -0800
    Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-01-28 22:55 -0800
      Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-01-28 23:03 -0800
    Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-02-06 22:37 -0800
      Re: Simple 2d C99 fractal plotter... "Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com> - 2019-02-11 13:44 -0800

csiph-web