Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Chris M. Thomasson's Hybrid Reverse 2-ary Julia
- Copyright (c) 6/4/2017
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- *_____________________________________________________________*/
- #include <stdlib.h>
- #include <stdio.h>
- #include <assert.h>
- #include <complex.h>
- #include <tgmath.h>
- #include <stdbool.h>
- #define CT_RAND() (rand() / (RAND_MAX - 0.0))
- struct ct_axes
- {
- double xmin;
- double xmax;
- double ymin;
- double ymax;
- };
- struct ct_color
- {
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
- };
- struct ct_canvas
- {
- unsigned long width;
- unsigned long height;
- struct ct_color* buf; // gxxx
- };
- bool
- ct_canvas_create(
- struct ct_canvas* const self,
- unsigned long width,
- unsigned long height
- ){
- size_t size = width * height * sizeof(*self->buf);
- 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 RIFC Cipher Renderer 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)
- {
- struct ct_color* c = &self->buf[i];
- fprintf(fout, "%u %u %u ", c->r, c->g, c->b);
- }
- if (! fclose(fout))
- {
- return true;
- }
- }
- return false;
- }
- struct ct_plane
- {
- struct ct_axes axes;
- struct ct_canvas* canvas;
- };
- size_t
- ct_plane_project(
- struct ct_plane const* const self,
- double complex c
- ){
- double awidth = self->axes.xmax - self->axes.xmin;
- double aheight = self->axes.ymax - self->axes.ymin;
- // assert for avoiding div-by-zero
- assert(self->canvas->width > 1 &&
- self->canvas->height > 1);
- double xstep = awidth / (self->canvas->width - 1.0);
- double ystep = aheight / (self->canvas->height - 1.0);
- size_t x = (creal(c) - self->axes.xmin) / xstep;
- size_t y = (self->axes.ymax - cimag(c)) / ystep;
- size_t i = x + y * self->canvas->height;
- return i;
- }
- bool
- ct_plane_plot(
- struct ct_plane* const self,
- double complex c,
- struct ct_color color
- ){
- size_t cp = ct_plane_project(self, c);
- if (cp < self->canvas->height * self->canvas->width)
- {
- self->canvas->buf[cp] = color;
- return true;
- }
- return false;
- }
- bool
- ct_plane_plot_gradient(
- struct ct_plane* const self,
- double complex c,
- struct ct_color color
- ){
- size_t cp = ct_plane_project(self, c);
- if (cp < self->canvas->height * self->canvas->width)
- {
- struct ct_color temp = self->canvas->buf[cp];
- color.r = temp.r + color.r;
- color.g = temp.g + color.g;
- color.b = temp.b + color.b;
- color.a = temp.a + color.a;
- if (color.r < temp.r) color.r = temp.r;
- if (color.g < temp.g) color.g = temp.g;
- if (color.b < temp.b) color.b = temp.b;
- if (color.a < temp.a) color.a = temp.a;
- self->canvas->buf[cp] = color;
- return true;
- }
- return false;
- }
- // selective light
- void
- ct_slight(
- struct ct_plane* const self
- ){
- size_t size = self->canvas->width * self->canvas->height;
- for (size_t i = 0; i < size; ++i)
- {
- struct ct_color* color = &self->canvas->buf[i];
- if (color->r > 0 && color->r < 10)
- {
- color->r = color->r * 123;
- color->g = color->g * 123;
- }
- /*
- if (color->r > 0 && color->r < 10)
- {
- color->r = (color->r + 13) * 13;
- }
- if (color->g > 0 && color->g < 10)
- {
- color->g = (color->g + 13) * 13;
- }
- */
- }
- }
- // Compute the forward fractal
- void
- ct_forward(
- struct ct_plane* const self,
- double complex z,
- double complex c,
- double ratio,
- unsigned long n
- ){
- for (unsigned long i = 0; i < n; ++i)
- {
- z = z*z + c;
- z = z * ratio;
- //struct ct_color c0 = { (i + 1) * 12345, i, i * 4, 0 };
- //ct_plane_plot(self, z, c0);
- struct ct_color c0 = { 2, i % 2, 2, 0 };
- ct_plane_plot_gradient(self, z, c0);
- }
- }
- // Compute the reverse fractal
- void
- ct_ifs(
- struct ct_plane* const self,
- double complex z,
- double complex c,
- double ratio,
- unsigned long n
- ){
- // 2 sets
- double complex jp[] = {
- .26 + I*0,
- -1.9 + I*.0
- };
- ratio = .95;
- printf("ct_ifs: %lf%+lfi, %lf%+lfi, ratio:%lf\n",
- creal(jp[0]), cimag(jp[0]),
- creal(jp[1]), cimag(jp[1]),
- ratio);
- for (unsigned long i = 0; i < n; ++i)
- {
- //double ir = i / (n - 1.);
- 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 > ratio)
- {
- z = -root;
- }
- ct_forward(self, z, z, .7, 5);
- struct ct_color c0 = { 2, 0, 0, 0 };
- struct ct_color c1 = { 0, 0, 2, 0 };
- /*
- double esc = .9;
- if (creal(z) > fabs(cos(ir * creal(z))) * esc)
- {
- z = -creal(z) * 1.4 + cimag(z) * I;
- }
- */
- ct_plane_plot_gradient(self, z, c0);
- ct_plane_plot_gradient(self, root, c1);
- if (! (i % 256))
- {
- printf("rendering: %lu of %lu\r", i + 1, n);
- }
- }
- printf("rendering: %lu of %lu\n", n, n);
- }
- #define CT_WIDTH 1024
- #define CT_HEIGHT 1024
- #define CT_N 20000000
- int main(void)
- {
- struct ct_canvas canvas;
- bool status = ct_canvas_create(&canvas, CT_WIDTH, CT_HEIGHT);
- assert(status);
- double radius = 2.25;
- struct ct_axes axes = { -radius, radius, -radius, radius };
- struct ct_plane plane = { axes, &canvas };
- // Julia circle at origin z and Julia point c = 0+0i
- double complex z = 0+0*I;
- double complex c = 0+0*I; // Julia
- double ratio = .5;
- ct_ifs(&plane, z, c, ratio, CT_N);
- ct_slight(&plane);
- status = ct_canvas_save_ppm(&canvas, "ct_cipher_rifc.ppm");
- assert(status);
- printf("\ncreated: ct_cipher_rifc.ppm\n");
- ct_canvas_destroy(&canvas);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment