From bec1e654ebab6f82c18e405326a75de3805ead20 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Mon, 16 Mar 2020 13:11:29 +0100 Subject: [PATCH] now we can render smaller parts of the set with higher resolution --- images/bmp-format.c | 3 +- main.c | 100 +++++++++++++++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/images/bmp-format.c b/images/bmp-format.c index fd1f9ee..9eb3698 100644 --- a/images/bmp-format.c +++ b/images/bmp-format.c @@ -58,9 +58,8 @@ int image_save_bmp(Image image, const char* path) { if ((unsigned long int) size > (unsigned long int) UINT_MAX) { printf("bitmap is too big!\n"); return 0; - } else { - printf("predicted size is %lu out of %u possible", size, UINT_MAX); } + FILE *fp = fopen(path, "w"); //unsigned char* bytes = calloc(sizeof(char), size); // magic bytes, signature "BM" diff --git a/main.c b/main.c index 448070b..aae7355 100644 --- a/main.c +++ b/main.c @@ -9,16 +9,58 @@ #include "complex.c" -#define MB_THREADS 7 +#define MB_THREADS 11 + +typedef struct _mb_settings { + unsigned int width; + unsigned int iterations; + double re_start; + double re_end; + double im_start; + double im_end; +} MandelbrotSettings; + +MandelbrotSettings mb_settings_default(int width, int iterations) { + MandelbrotSettings set; + set.width = width; + set.iterations = iterations; + set.re_start = -2; + set.re_end = 1; + set.im_start = -1.25; + set.im_end = 1.25; + return set; +} + +MandelbrotSettings mb_settings_at_pt(int width, int iterations, double re, double im, double px_step) { + MandelbrotSettings set; + set.width = width; + int height = width; + set.iterations = iterations; + set.re_start = re - (width * (0.5 *px_step)); + set.re_end = re + (width * (0.5 *px_step)); + set.im_start = im - (height * (0.5 *px_step)); + set.im_end = im + (height * (0.5 *px_step)); + return set; +} -void draw_mandelbrot(int width, int height, int iterations); -void draw_mandelbrot_auto(int width, int iterations); -int test_mandelbrot(Complex c, int iterations); +void mb_print_settings(MandelbrotSettings set) { + printf( + "Settings: {\n\twidth; %d\n\titerations; %d\n\tre_start; %f\n\tre_end; %f\n\tim_start; %f\n\tim_end; %f\n}\n", + set.width, + set.iterations, + set.re_start, + set.re_end, + set.im_start, + set.im_end + ); +} + +void draw_mandelbrot(MandelbrotSettings settings); +unsigned int test_mandelbrot(Complex c, int iterations); void* create_shared_memory(size_t size); int image_new_shared(int width, int height, Image* img); void image_destroy_shared(Image img); - int main(int argc, char* argv[]) { int width = 3000; int iterations = 60; @@ -29,24 +71,30 @@ int main(int argc, char* argv[]) { iterations = atoi(argv[2]); } - draw_mandelbrot_auto(width, iterations); -} + double step = (1/ (double) 18) / width; -void draw_mandelbrot_auto(int width, int iterations) { - draw_mandelbrot(width, 2.5f * width / 3, iterations); + MandelbrotSettings set = mb_settings_at_pt( + width, iterations, -1, -(2.2/(double)9), step + ); + + mb_print_settings(set); + + draw_mandelbrot(set); } -void draw_mandelbrot(int width, int height, int iterations) { - int center_x = 2 * width / 3; - int center_y = height / 2; - float step = 3.0f / width; + +void draw_mandelbrot(MandelbrotSettings set) { + double step = (set.re_end - set.re_start) / set.width; + unsigned int height = (set.im_end - set.im_start) / step; + + printf("Dimensions: %ux%u (step: %f)\n", set.width, height, step); Image img; - image_new_shared(width, height, &img); + image_new_shared(set.width, height, &img); - int thread_id = 0; + unsigned int thread_id = 0; - for (int i = 0; i < MB_THREADS - 1; i++) { + for (unsigned int i = 0; i < MB_THREADS - 1; i++) { if (fork() == 0) { thread_id = i + 1; break; @@ -54,20 +102,25 @@ void draw_mandelbrot(int width, int height, int iterations) { } printf("Thread %i reporting for duty\n", thread_id); - for (int x = 0; x < width; x++) { + for (unsigned int x = 0; x < set.width; x++) { if (x % MB_THREADS != thread_id) continue; - for (int y = 0; y < height; y++) { + if (x % (set.width / 100) == 0) { + printf("Rendering... %02i%%\r", (int) ((x / (float) set.width) * 100)); + fflush(stdout); + } + + for (unsigned int y = 0; y < height; y++) { Complex c = complex_new( - (x - center_x) * step, - (y - center_y) * step + set.re_start + (x * step), + set.im_start + (y * step) ); - int ret = test_mandelbrot(c, iterations); + unsigned int ret = test_mandelbrot(c, set.iterations); //int r = (ret * 160 / iterations); //int g = (ret * 9 / iterations); //int b = (ret * 165 / iterations); //image_set_px(img, x, y, r,g,b); - int color = 255 * sqrt(ret / (float) iterations); + int color = 255 * sqrt(ret / (float) set.iterations); image_set_px(img, x, y, color, color, color); } } @@ -79,7 +132,6 @@ void draw_mandelbrot(int width, int height, int iterations) { int status; for (int i = 0; i < MB_THREADS - 1; i++) { - printf("Waiting for threads... %d/%d\n", i, MB_THREADS - 1); while(wait(&status) > 0) {} } @@ -89,7 +141,7 @@ void draw_mandelbrot(int width, int height, int iterations) { image_destroy_shared(img); } -int test_mandelbrot(Complex c, int iterations) { +unsigned int test_mandelbrot(Complex c, int iterations) { Complex z = complex_new(0,0); for (int i = 0; i < iterations; i++) {