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;
}