aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--README.md5
-rw-r--r--algorithms.h2
-rw-r--r--algorithms/burning-ship-lattice.c65
-rw-r--r--algorithms/burning-ship.c16
-rw-r--r--algorithms/mandelbrot.c16
-rwxr-xr-xextra/burning-ship-lattice-gen.sh3
-rw-r--r--fractal-gen.c29
-rw-r--r--fractal-gen.h8
9 files changed, 60 insertions, 87 deletions
diff --git a/Makefile b/Makefile
index 3256e60..a2f4358 100644
--- a/Makefile
+++ b/Makefile
@@ -5,19 +5,16 @@ all: fractal-gen symlinks
symlinks: fractal-gen
ln -sf $< mandelbrot-gen
ln -sf $< burning-ship-gen
- ln -sf $< burning-ship-lattice-gen
fractal-gen: fractal-gen.o \
algorithms/mandelbrot.o \
algorithms/burning-ship.o \
- algorithms/burning-ship-lattice.o \
clean: clean-object
rm fractal-gen \
mandelbrot-gen \
burning-ship-gen \
- burning-ship-lattice-gen \
-f
clean-object:
diff --git a/README.md b/README.md
index f14836e..905be3c 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,7 @@ This is a tiny program which will output a binary [PGM](https://wikipedia.org/wi
./mandelbrot-gen -s size -i max_iterations [-e exponent] \
[-c cores] [-t thread_multiplier]
+ [-x left -y top] [-z scale]
[-N cluster-id -T cluster-total] > output.pgm
Also check out the other algorithms like `tricorn-gen` and `burning-ship-gen`.
@@ -34,6 +35,10 @@ Also note that `-N` should always be used together with `-T`.
-t thread_multiplier Float > 0
Coefficient to multiply cores by in order to achieve
count of worker threads to use. (1)
+ -x left position of left of image on the real axis (x+iy)
+ -y top position of top of image on the imaginary axis (x+iy)
+ -z scale width and height of image in units on the cartesian
+ plane
-N cluster_id 0 <= Integer < cluster_total
A unique ID used to determine which sections of the
image this instance should work on.
diff --git a/algorithms.h b/algorithms.h
index bc83c12..eddeb3b 100644
--- a/algorithms.h
+++ b/algorithms.h
@@ -27,5 +27,3 @@
void *generate_mandelbrot_section(void *section);
void *generate_burning_ship_section(void *section);
-void *generate_burning_ship_lattice_section(void *section);
-void *generate_tricorn_section(void *section);
diff --git a/algorithms/burning-ship-lattice.c b/algorithms/burning-ship-lattice.c
deleted file mode 100644
index 6a7241e..0000000
--- a/algorithms/burning-ship-lattice.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Part of fractal-gen - Generate iteration-based fractals in PNM format
- * Copyright (c) 2016 David Phillips <dbphillipsnz@gmail.com>
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "common.h"
-
-void
-*generate_burning_ship_lattice_section(void *section)
-{
- data_section *d = (data_section*)section;
- unsigned int x = 0;
- unsigned int y = 0;
- unsigned int i = 0;;
- double a = 0;
- double b = 0;
- double complex z = 0;
- double complex c = 0;
- double size_units = 0.09f;
- double top = -0.082f;
- double left = -1.8f;
-
- /* FIXME document this */
- b = clust_id*(size_units/size)+top; /* FIXME document this */
-
- for (y = clust_id; y < size; y+=clust_total) {
- a = d->core*(size_units/size)+left;
- for (x = d->core; x < size; x += cores) {
- z = 0;
- c = a+I*b;
- for (i = 0; i < iterat; i++) {
- if (cabs(z) >= 2)
- break;
-
- z = cpow( fabs(creal(z)) + I*fabs(cimag(z)) , power) + c;
- }
- d->data[d->idx++] = (255*i)/iterat;
- a += cores*(size_units/size);
- }
- b += clust_total*(size_units/size);
- }
- return NULL;
-}
diff --git a/algorithms/burning-ship.c b/algorithms/burning-ship.c
index 56323ac..7e27e4b 100644
--- a/algorithms/burning-ship.c
+++ b/algorithms/burning-ship.c
@@ -31,18 +31,20 @@ void
*generate_burning_ship_section(void *section)
{
data_section *d = (data_section*)section;
+ struct frame *f = &(d->parent_frame);
unsigned int x,y,i;
double a,b;
double complex z,c;
- double size_units = 3.5f;
- double top = -2.2f;
- double left = -2.2f;
+
+ defaultsd(&d->parent_frame.scale, 3.5f);
+ defaultsd(&d->parent_frame.top, -2.2f);
+ defaultsd(&d->parent_frame.left, -2.2f);
/* FIXME document this */
- b = clust_id*(size_units/size)+top; /* FIXME document this */
+ b = clust_id*(f->scale/size)+f->top; /* FIXME document this */
for (y = clust_id; y < size; y += clust_total) {
- a = d->core*(size_units/size)+left;
+ a = d->core*(f->scale/size)+f->left;
for (x = d->core; x < size; x += cores) {
z = 0;
c = a+I*b;
@@ -53,9 +55,9 @@ void
z = cpow( fabs(creal(z)) + I*fabs(cimag(z)) , power) + c;
}
d->data[d->idx++] = (255*i)/iterat;
- a += cores*(size_units/size);
+ a += cores*(f->scale/size);
}
- b += clust_total*(size_units/size);
+ b += clust_total*(f->scale/size);
}
return NULL;
}
diff --git a/algorithms/mandelbrot.c b/algorithms/mandelbrot.c
index 67da2c6..51d0c43 100644
--- a/algorithms/mandelbrot.c
+++ b/algorithms/mandelbrot.c
@@ -31,19 +31,21 @@ void
*generate_mandelbrot_section(void *section)
{
data_section *d = (data_section*)section;
+ struct frame *f = &(d->parent_frame);
unsigned int x,y,i;
double a,b;
double complex z,c;
- double size_units = 3.5f;
- double top = -1.75f;
- double left = -2.5f;
+
+ defaultsd(&d->parent_frame.top, -1.75f);
+ defaultsd(&d->parent_frame.left, -2.5f);
+ defaultsd(&d->parent_frame.scale, 3.5f);
/* FIXME document this */
- b = clust_id*(size_units/size)+top; /* FIXME document this */
+ b = clust_id*(f->scale/size)+f->top; /* FIXME document this */
for (y = clust_id; y < size; y += clust_total) {
- a = d->core*(size_units/size)+left;
+ a = d->core*(f->scale/size)+f->left;
for (x = d->core; x < size; x += cores) {
z = 0;
c = a + I*b;
@@ -54,9 +56,9 @@ void
z = cpow(z , power) + c;
}
d->data[d->idx++] = (255*i)/iterat;
- a += cores*(size_units/size);
+ a += cores*(f->scale/size);
}
- b += clust_total*(size_units/size);
+ b += clust_total*(f->scale/size);
}
return NULL;
}
diff --git a/extra/burning-ship-lattice-gen.sh b/extra/burning-ship-lattice-gen.sh
new file mode 100755
index 0000000..1a39c0d
--- /dev/null
+++ b/extra/burning-ship-lattice-gen.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec ./burning-ship-gen -x -1.8 -y -0.082 -z 0.09 $@
diff --git a/fractal-gen.c b/fractal-gen.c
index 0d2e1a3..e80c96a 100644
--- a/fractal-gen.c
+++ b/fractal-gen.c
@@ -37,10 +37,11 @@
#include <sys/mman.h>
#include <string.h>
+struct frame f;
+
static struct section_generator generators[] = {
{ "mandelbrot-gen" , &generate_mandelbrot_section },
- { "burning-ship-gen" , &generate_burning_ship_section },
- { "burning-ship-lattice-gen" , &generate_burning_ship_lattice_section }
+ { "burning-ship-gen" , &generate_burning_ship_section }
};
char *ram_units[] = {
@@ -48,6 +49,13 @@ char *ram_units[] = {
};
+void
+defaultsd(double *who, double def)
+{
+ if (isnan(*who))
+ *who = def;
+}
+
int
main(int argc, char **argv)
{
@@ -129,8 +137,12 @@ main(int argc, char **argv)
munmap(sections, sizeof(data_section)*cores);
return 1;
}
+ /* FIXME repetition */
sections[i].core = i;
sections[i].width = width;
+ sections[i].parent_frame.top = f.top;
+ sections[i].parent_frame.left = f.left;
+ sections[i].parent_frame.scale = f.scale;
sections[i].datasize = toalloc;
fprintf(stderr, " -> Thread %lu\r", i);
pthread_create(&sections[i].thread, NULL, generator, &(sections[i]));
@@ -195,20 +207,31 @@ parse_args(int argc, char **argv)
clust_id = 0;
clust_total = 1;
+ f.left = nan("");
+ f.top = nan("");
+ f.scale = nan("");
+
/* bail out early if no arguments are supplied */
if (argc <= 1)
return 1;
- while ( (opt = getopt(argc, argv, "s:i:e:c:t:N:T:")) != -1 ) {
+ while ( (opt = getopt(argc, argv, "s:i:e:c:t:N:T:x:y:z:")) != -1 ) {
switch (opt)
{
case 's': size = atoi(optarg); break;
case 'i': iterat = atoi(optarg); break;
case 'e': power = atof(optarg); break;
+
case 'c': cores = atoi(optarg); break;
case 't': thread_mult = atof(optarg); break;
+
case 'N': clust_id = atoi(optarg); break;
case 'T': clust_total = atoi(optarg); break;
+
+ case 'x': f.left = atof(optarg); break;
+ case 'y': f.top = atof(optarg); break;
+ case 'z': f.scale = atof(optarg); break;
+
/* redundant case for '?', but explicitness is best */
case '?':
default:
diff --git a/fractal-gen.h b/fractal-gen.h
index 21d4ca5..a103d1f 100644
--- a/fractal-gen.h
+++ b/fractal-gen.h
@@ -28,8 +28,15 @@
#include <stdbool.h>
#include <pthread.h>
+struct frame {
+ double top;
+ double left;
+ double scale;
+};
+
typedef struct {
volatile unsigned long idx;
+ struct frame parent_frame;
unsigned long core;
unsigned long width;
unsigned long datasize;
@@ -48,6 +55,7 @@ char *argv0;
typedef void* (*generator_func)(void *);
+void defaultsd(double*, double);
int parse_args(int argc, char **argv);
generator_func select_generator(const char* name);
void show_help();