Mandelbrot分形輸出到BMP

Mandelbrot分形,目前生成的圖案還不甚理想。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct complex_struct
{
	double real;
	double image;
} complex;

complex complex_add(complex a, complex b)
{
	complex c;

	// (a + bi) + (c + di) = (a + c) + (b + d)i
	c.real = a.real + b.real;
	c.image = a.image + b.image;

	return c;
}

complex complex_sub(complex a, complex b)
{
	complex c;

	// (a + bi) - (c + di) = (a - c) + (b - d)i
	c.real = a.real - b.real;
	c.image = a.image - b.image;

	return c;
}

complex complex_mul(complex a, complex b)
{
	complex c;

	// (a + bi) * (c + di) = (ac - bd) + (bc + ad)i
	c.real = a.real * b.real - a.image * b.image;
	c.image = a.image * b.real + a.real * b.image;

	return c;
}

complex complex_div(complex a, complex b)
{
	complex c;

	double c2d2 = b.real * b.real + b.image * b.image;

	// (a + bi) / (c + di) = (a + bi) * (c - di) / (c * c + d * d)
	// = ((ac + bd) + (bc - ad)i) / (c * c + d * d)
	c.real = (a.real * b.real + a.image * b.image) / c2d2;
	c.image = (a.image * b.real - a.real * b.image) / c2d2;

	return c;
}

int mandelbrot(complex z0)
{
	complex z = z0;
	int i, color;

	// z = z0
	// z = z * z + z0
	for(i = 0; i < 8 * 8 * 8; i++)
	{
		z = complex_add(complex_mul(z, z), z0);

		if((z.real * z.real + z.image * z.image) >= 4) break;
	}

	return i;
}

void Test24Bit(const char *file24bit)
{
	static unsigned char BitmapHeader24bit[] =
	{
		0x42, 0x4D, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, //  2 AA->FileSize
		0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0x28, 0x00, // 10 BB->OffBits
		0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xDD, 0xDD, // 18 CC->Width
		0xDD, 0xDD, 0x01, 0x00, 0xEE, 0xEE, 0x00, 0x00, // 22 DD->Height
		0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, // 28 EE->BitCount
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 34 FF->ImageSize
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

	int i, w, h;

	int r, g, b, color;

	struct BMPINFO
	{
		long width;
		long height;
		short bitcount;
		long widthbyte;
		long imagesize;
		long palettesize;
		long offbits;
		long filesize;
	} bmp24bit;

	complex z;

	// getting pixels and dimensions
	unsigned char *imgrow = NULL;
	FILE *fp24bit = NULL;
	do
	{
		fp24bit = fopen(file24bit, "wb");
		if(fp24bit == NULL) break;

		// bitmap header
		bmp24bit.width = 1024;
		bmp24bit.height = 1024;
		bmp24bit.bitcount = 24;
		bmp24bit.widthbyte = (bmp24bit.width * bmp24bit.bitcount + 31) / 32 * 4;
		bmp24bit.imagesize = bmp24bit.widthbyte * bmp24bit.height;
		bmp24bit.palettesize = 0;
		bmp24bit.offbits = sizeof(BitmapHeader24bit) + bmp24bit.palettesize;
		bmp24bit.filesize = sizeof(BitmapHeader24bit) + bmp24bit.palettesize + bmp24bit.imagesize;

		*((long *)(BitmapHeader24bit +  2)) = bmp24bit.filesize;
		*((long *)(BitmapHeader24bit + 10)) = bmp24bit.offbits;
		*((long *)(BitmapHeader24bit + 18)) = bmp24bit.width;
		*((long *)(BitmapHeader24bit + 22)) = bmp24bit.height;
		*((short *)(BitmapHeader24bit + 28)) = bmp24bit.bitcount;
		*((long *)(BitmapHeader24bit + 34)) = bmp24bit.imagesize;

		imgrow = malloc(bmp24bit.widthbyte);
		if(imgrow == NULL) break;

		fwrite(BitmapHeader24bit, sizeof(BitmapHeader24bit), 1L, fp24bit);

		for(h = 0; h < bmp24bit.height; h++)
		{
			for(w = 0; w < bmp24bit.width; w++)
			{
				z.real = 3.2 * w / (bmp24bit.width - 1) - 2.1;
				z.image = 3.2 * h / (bmp24bit.height - 1) - 1.6;
				color = mandelbrot(z);
				color <<= 10;
				memcpy(imgrow + 3 * w, &color, 3);
			}

			if((1000 * h / bmp24bit.height) != (1000 * (h - 1) / bmp24bit.height))
			{
				printf("\b\b\b\b\b\b\b\b");
				printf("%.1f%%", 100.0 * h / bmp24bit.height);
			}

			fwrite(imgrow, bmp24bit.widthbyte, 1L, fp24bit);
		}

	} while(0);

	if(imgrow) free(imgrow);
	if(fp24bit) fclose(fp24bit);
}

int main()
{
	Test24Bit("D:\\test.bmp");

	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章