c-exercises/mandelbrot.c

88 lines
1.9 KiB
C
Raw Normal View History

2013-05-10 23:57:48 +02:00
#include "SDL.h"
#include <complex.h>
#include <stdbool.h>
2013-05-13 13:59:12 +02:00
/* The maximum iteration count. */
const int max_it = 170;
2013-05-11 21:34:34 +02:00
/* Compute the out-coloring based on the iteration counter. */
Uint32 outcolor(int it) {
2013-05-13 13:59:12 +02:00
return 0x00010001 * ((it * 0xff) / max_it);
2013-05-11 21:34:34 +02:00
}
2013-05-10 23:57:48 +02:00
2013-05-13 13:59:12 +02:00
/* "Compute" the in-coloring. */
2013-05-11 21:34:34 +02:00
Uint32 incolor() {
return 0x00000000; /* black */
}
void drawmandelbrot(SDL_Surface *surface) {
if (SDL_MUSTLOCK(surface)) {
SDL_LockSurface(surface);
2013-05-10 23:57:48 +02:00
}
2013-05-11 21:34:34 +02:00
Uint32 *pixels = (Uint32 *) surface->pixels;
for (int i = 0; i < surface->w * surface->h; i++) {
int y = i / surface->w;
int x = i % surface->w;
2013-05-10 23:57:48 +02:00
2013-05-15 10:34:03 +02:00
float complex c = ((3.0f * x / surface->w) - 2.0f)
+ I * ((2.0f * y / surface->h) - 1.0f);
2013-05-10 23:57:48 +02:00
bool diverges = false;
float complex z = 0;
int it;
2013-05-12 11:15:15 +02:00
for (it = 1; it <= max_it; it++) {
/* z = z² + c */
2013-05-10 23:57:48 +02:00
z = cpowf(z, 2) + c;
2013-05-12 11:15:15 +02:00
/* If |z| ever gets greater than 2, it diverges. */
2013-05-13 13:38:56 +02:00
if (cabsf(z) > 2) {
2013-05-10 23:57:48 +02:00
diverges = true;
break;
}
}
2013-05-11 13:10:00 +02:00
Uint32 color;
2013-05-10 23:57:48 +02:00
if (diverges) {
2013-05-11 21:34:34 +02:00
color = outcolor(it);
2013-05-11 13:10:00 +02:00
} else {
2013-05-11 21:34:34 +02:00
color = incolor();
2013-05-10 23:57:48 +02:00
}
pixels[i] = color;
2013-05-11 21:34:34 +02:00
/* Update the screen every 10 lines. */
if (y % 10 == 0 && x == 0) {
2013-05-11 21:34:34 +02:00
SDL_Flip(surface);
}
2013-05-10 23:57:48 +02:00
}
2013-05-11 16:02:40 +02:00
2013-05-11 21:44:30 +02:00
/* Update the screen a final time. */
SDL_Flip(surface);
2013-05-11 21:34:34 +02:00
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
}
int main(int argc, char *argv[]) {
/* Set up SDL. */
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
fprintf(stderr, "Error: Could not initialize SDL: %s.\n", SDL_GetError());
exit(1);
}
SDL_Surface *screen = SDL_SetVideoMode(320, 240, 32, SDL_SWSURFACE);
2013-05-13 14:45:46 +02:00
2013-05-11 21:34:34 +02:00
/* Do the mandelbrot. */
drawmandelbrot(screen);
2013-05-11 16:02:40 +02:00
/* Save BMP */
char *file = "mandelbrot.bmp";
if (SDL_SaveBMP(screen, file) != 0) {
fprintf(stderr, "Could not write %s!\n", file);
}
2013-05-11 21:34:34 +02:00
/* Quit. */
2013-05-10 23:57:48 +02:00
SDL_Delay(20000);
SDL_Quit();
}