r4880 - trunk/misc
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Oct 26 07:54:27 EDT 2008
Author: div0
Date: 2008-10-26 07:54:27 -0400 (Sun, 26 Oct 2008)
New Revision: 4880
Modified:
trunk/misc/spherefunc2skybox.c
Log:
allow mandelbrot to be parametrized; add some cool parameters for a start
Modified: trunk/misc/spherefunc2skybox.c
===================================================================
--- trunk/misc/spherefunc2skybox.c 2008-10-25 20:36:12 UTC (rev 4879)
+++ trunk/misc/spherefunc2skybox.c 2008-10-26 11:54:27 UTC (rev 4880)
@@ -3,7 +3,13 @@
#include <stdint.h>
#include <math.h>
#include <string.h>
+#include <stdlib.h>
+double rnd()
+{
+ return rand() / (RAND_MAX + 1.0);
+}
+
typedef void (*mapfunc_t) (double x_in, double y_in, double *x_out, double *y_out, double *z_out);
typedef void (*colorfunc_t) (double x, double y, double z, double *r, double *g, double *b);
@@ -15,31 +21,124 @@
*b = 0.5 + 0.5 * z;
}
-#define MAXITER 4096
-double mandelbrot(double zx, double zy, double cx, double cy)
+double mandelbrot_iter(double zx, double zy, double cx, double cy, int maxiter)
{
double tmp;
int i;
- for(i = 1; i < MAXITER; ++i)
+ double f, fprev;
+
+ f = 0;
+
+ for(i = 1; i < maxiter; ++i)
{
tmp = zx;
zx = zx * zx - zy * zy + cx;
zy = 2 * tmp * zy + cy;
- if(zx * zx + zy * zy > 4)
+ fprev = f;
+ f = zx * zx + zy * zy;
+ if(f > 4)
break;
}
- return ((i - 1.0) * MAXITER) / (i * (MAXITER - 1.0));
+ if(i >= maxiter)
+ return i;
+ else
+ {
+ // f: the greater, the more in 0 direction
+ // the smaller, the more in 1 direction
+ // fprev:
+ // the greater, the more in 0 direction
+ return i + 1 / (f - 4 + 1); // f = 16: + 0, f = 4: + 1
+ }
// i.e. 0 for i=1, 1 for i=maxiter
}
+double mandelbrot_range(double zx, double zy, double cx, double cy, int maxiter, double offset)
+{
+ double i = mandelbrot_iter(zx, zy, cx, cy, maxiter);
+ // map linearily 1/(offset + iter) so that:
+ // 0 -> 0
+ // maxiter -> 1
+ // i.e. solve:
+ // f(iter) = A/(offset + iter) + B
+ // that is:
+ // f(0) = A/offset + B = 0
+ // f(maxiter) = A/(offset + maxiter) + B = 1
+ // -->
+ // 1/(1/(offset + maxiter) - 1/offset) = A
+ // B = 1 + offset / maxiter
+ // A = -offset (1 + offset / maxiter)
+ // -->
+ // f(iter) = -offset (1 + offset / maxiter) / (offset + iter) + 1 + offset / maxiter
+ // = -offset (1 + offset / maxiter) / (offset + iter) + 1 + offset / maxiter
+ // = iter (offset + maxiter) / maxiter (offset + iter)
+ return (i * (offset + maxiter)) / ((i + offset) * maxiter);
+}
+
+double color_mandelbrot_parms[13];
+double mandelbrot_miniter = -1;
+#define MAXITER 8192
+
+double iter_mandelbrot_raw(double x, double y, double z)
+{
+ z -= color_mandelbrot_parms[6];
+ x /= fabs(z);
+ y /= fabs(z);
+
+ if(z > 0)
+ return mandelbrot_range(color_mandelbrot_parms[4], color_mandelbrot_parms[5], color_mandelbrot_parms[0] + x * color_mandelbrot_parms[2], color_mandelbrot_parms[1] + y * color_mandelbrot_parms[3], MAXITER, color_mandelbrot_parms[9]);
+ else
+ return 0;
+}
+
+void iter_mandelbrot_raw_initialize_min()
+{
+ if(mandelbrot_miniter >= 0)
+ return;
+ // randomly sample 256 points
+ // mandelbrot them
+ // set that as miniter
+ int i = 0;
+ double x, y, z;
+ mandelbrot_miniter = MAXITER;
+ for(i = 0; i < 8192; ++i)
+ {
+ x = rnd() * 2 - 1;
+ y = rnd() * 2 - 1;
+ z = rnd() * 2 - 1;
+ double f = sqrt(x*x + y*y + z*z);
+ x /= f;
+ y /= f;
+ z /= f;
+ double a = (z - color_mandelbrot_parms[6]) / (color_mandelbrot_parms[7] - color_mandelbrot_parms[6]);
+ a = (a - color_mandelbrot_parms[8]) / (1 - color_mandelbrot_parms[8]);
+ if(a < 1)
+ continue;
+ double iterations = iter_mandelbrot_raw(x, y, z);
+ if(iterations == 0)
+ continue;
+ if(iterations < mandelbrot_miniter)
+ mandelbrot_miniter = iterations;
+ }
+}
+
void color_mandelbrot(double x, double y, double z, double *r, double *g, double *b)
{
- double iterations = mandelbrot(0, z*0.5, x - 1, y);
- *r = pow(iterations, 100);
- *g = pow(iterations, 25);
- *b = pow(iterations, 10);
+ iter_mandelbrot_raw_initialize_min();
+
+ double iterations = iter_mandelbrot_raw(x, y, z);
+ //printf("iter = %f\n", iterations);
+ double a = (z - color_mandelbrot_parms[6]) / (color_mandelbrot_parms[7] - color_mandelbrot_parms[6]);
+ a = (a - color_mandelbrot_parms[8]) / (1 - color_mandelbrot_parms[8]);
+ if(a < 0)
+ a = 0;
+ if(a > 1)
+ a = 1;
+ iterations = iterations * a + mandelbrot_miniter * (1-a);
+ *r = pow(iterations, color_mandelbrot_parms[10]);
+ *g = pow(iterations, color_mandelbrot_parms[11]);
+ *b = pow(iterations, color_mandelbrot_parms[12]);
}
void map_back(double x_in, double y_in, double *x_out, double *y_out, double *z_out)
@@ -84,10 +183,7 @@
*z_out = -1;
}
-#define WIDTH 512
-#define HEIGHT 512
-
-void writepic(colorfunc_t f, mapfunc_t m, const char *fn)
+void writepic(colorfunc_t f, mapfunc_t m, const char *fn, int width, int height)
{
int x, y;
uint8_t tga[18];
@@ -98,53 +194,76 @@
memset(tga, 0, sizeof(tga));
tga[2] = 2; // uncompressed type
- tga[12] = (WIDTH >> 0) & 0xFF;
- tga[13] = (WIDTH >> 8) & 0xFF;
- tga[14] = (HEIGHT >> 0) & 0xFF;
- tga[15] = (HEIGHT >> 8) & 0xFF;
+ tga[12] = (width >> 0) & 0xFF;
+ tga[13] = (width >> 8) & 0xFF;
+ tga[14] = (height >> 0) & 0xFF;
+ tga[15] = (height >> 8) & 0xFF;
tga[16] = 24; // pixel size
fwrite(&tga, sizeof(tga), 1, file);
- for(y = HEIGHT-1; y >= 0; --y)
- for(x = 0; x < WIDTH; ++x)
+ for(y = height-1; y >= 0; --y)
+ for(x = 0; x < width; ++x)
{
uint8_t rgb[3];
double rr, gg, bb;
double xx, yy;
double xxx, yyy, zzz;
double r;
- xx = (x + 0.5) / WIDTH;
- yy = (y + 0.5) / HEIGHT;
+ xx = (x + 0.5) / width;
+ yy = (y + 0.5) / height;
m(xx, yy, &xxx, &yyy, &zzz);
r = sqrt(xxx*xxx + yyy*yyy + zzz*zzz);
xxx /= r;
yyy /= r;
zzz /= r;
f(xxx, yyy, zzz, &rr, &gg, &bb);
- rgb[2] = floor(0.5 + rr * 255);
- rgb[1] = floor(0.5 + gg * 255);
- rgb[0] = floor(0.5 + bb * 255);
+ rgb[2] = floor(rnd() + rr * 255);
+ rgb[1] = floor(rnd() + gg * 255);
+ rgb[0] = floor(rnd() + bb * 255);
fwrite(rgb, sizeof(rgb), 1, file);
}
fclose(file);
}
-void map_all(const char *fn, colorfunc_t f)
+void map_all(const char *fn, colorfunc_t f, int width, int height)
{
char buf[1024];
- snprintf(buf, sizeof(buf), "%s_bk.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_back, buf);
- snprintf(buf, sizeof(buf), "%s_ft.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_front, buf);
- snprintf(buf, sizeof(buf), "%s_rt.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_right, buf);
- snprintf(buf, sizeof(buf), "%s_lf.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_left, buf);
- snprintf(buf, sizeof(buf), "%s_up.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_up, buf);
- snprintf(buf, sizeof(buf), "%s_dn.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_down, buf);
+ snprintf(buf, sizeof(buf), "%s_bk.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_back, buf, width, height);
+ snprintf(buf, sizeof(buf), "%s_ft.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_front, buf, width, height);
+ snprintf(buf, sizeof(buf), "%s_rt.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_right, buf, width, height);
+ snprintf(buf, sizeof(buf), "%s_lf.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_left, buf, width, height);
+ snprintf(buf, sizeof(buf), "%s_up.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_up, buf, width, height);
+ snprintf(buf, sizeof(buf), "%s_dn.tga", fn); buf[sizeof(buf) - 1] = 0; writepic(f, map_down, buf, width, height);
}
int main(int argc, char **argv)
{
- if(argc != 2)
- errx(1, "file name argument missing");
- map_all(argv[1], color_mandelbrot);
+ colorfunc_t f;
+ if(argc < 4)
+ errx(1, "usage: %s filename res func parms...", *argv);
+ int res = atoi(argv[2]);
+ if(!strcmp(argv[3], "mandel"))
+ {
+ f = color_mandelbrot;
+ color_mandelbrot_parms[0] = argc<= 4 ? -0.740 : atof(argv[4]); // shift xy
+ color_mandelbrot_parms[1] = argc<= 5 ? -0.314 : atof(argv[5]);
+ color_mandelbrot_parms[2] = argc<= 6 ? -0.003 : atof(argv[6]); // mul xy
+ color_mandelbrot_parms[3] = argc<= 7 ? -0.003 : atof(argv[7]);
+ color_mandelbrot_parms[4] = argc<= 8 ? 0.420 : atof(argv[8]); // shift z
+ color_mandelbrot_parms[5] = argc<= 9 ? 0.000 : atof(argv[9]);
+ color_mandelbrot_parms[6] = argc<=10 ? -0.8 : atof(argv[10]); // horizon
+ color_mandelbrot_parms[7] = argc<=11 ? -0.7 : atof(argv[11]);
+ color_mandelbrot_parms[8] = argc<=12 ? 0.5 : atof(argv[12]);
+ color_mandelbrot_parms[9] = argc<=13 ? 400 : atof(argv[13]); // coloring
+ color_mandelbrot_parms[10] = argc<=14 ? 0.6 : atof(argv[14]);
+ color_mandelbrot_parms[11] = argc<=15 ? 0.5 : atof(argv[15]);
+ color_mandelbrot_parms[12] = argc<=16 ? 0.2 : atof(argv[16]);
+ }
+ else
+ {
+ f = color_test;
+ }
+ map_all(argv[1], color_mandelbrot, res, res);
return 0;
}
More information about the nexuiz-commits
mailing list