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