-
Notifications
You must be signed in to change notification settings - Fork 0
/
mandelbrot.c
122 lines (97 loc) · 2.99 KB
/
mandelbrot.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#import <stdlib.h>
#import <stdio.h>
#import <math.h>
#define MIN_X -2.25
#define MAX_X 1.0
#define MIN_Y -1.25
#define MAX_Y 1.25
#define COLORS 250
#define START_COLOR { 3, 18, 33 }
#define MIDDLE_COLOR { 255, 255, 255 }
#define END_COLOR { 144, 82, 13 }
typedef struct {
int screenX;
int screenY;
int iterations;
} Config;
typedef struct {
float red;
float green;
float blue;
} Color;
void usage(char filename[]) {
printf("usage: %s x y iterations", filename);
}
void palette_from_to(Color palette[], Color colstart, Color colend, int start, int max) {
int cnt = max - start;
float rfact = (float)(colend.red - colstart.red) / cnt;
float gfact = (float)(colend.green - colstart.green) / cnt;
float bfact = (float)(colend.blue - colstart.blue) / cnt;
int i;
for(i = 1; i<=cnt; i++) {
float red = (float)colstart.red + rfact * (float)i;
float green = (float)colstart.green + gfact * (float)i;
float blue = (float)colstart.blue + bfact * (float)i;
Color current = { red, green, blue };
palette[start+i-1] = current;
}
}
void palette_generate(Color palette[]) {
Color start = START_COLOR;
Color middle = MIDDLE_COLOR;
Color end = END_COLOR;
palette_from_to(palette, start, middle, 0, COLORS / 4);
palette_from_to(palette, middle, end, COLORS / 4, COLORS);
}
void init_ppm(Config conf) {
// Line 1: P3 means colors are in ASCII
// Line 2: Resolution for X Y,
// Line 3: Colors 255 per channel
printf("P3\n");
printf("%d %d\n", conf.screenX, conf.screenY);
printf("255\n");
}
void plot(int x, int y, Color c) {
printf("%03d %03d %03d ", (int)(c.red), (int)(c.green), (int)(c.blue));
}
int main(int argc, char *argv[]) {
int sy, sx;
if(argc != 4) {
usage(argv[0]);
return 1;
}
Config conf = { atoi(argv[1]), atoi(argv[2]), atoi(argv[3]) };
if(conf.screenX == 0 || conf.screenY == 0 || conf.iterations == 0) {
usage(argv[0]);
return 1;
}
Color palette[COLORS];
palette_generate(palette);
init_ppm(conf);
float xrange = MAX_X - MIN_X;
float yrange = MAX_Y - MIN_Y;
for(sy = 1; sy <= conf.screenY; sy++) {
for(sx = 1; sx <= conf.screenX; sx++) {
float x, y;
x = 0.0;
y = 0.0;
float x0 = sx / (float)conf.screenX * xrange + MIN_X;
float y0 = sy / (float)conf.screenY * yrange + MIN_Y;
int i = 0;
while(((x*x - y*y) < (2*2)) && i < conf.iterations) {
float xtmp;
xtmp = x*x - y*y + x0;
y = 2*x*y + y0;
x = xtmp;
i++;
}
Color c = { 0, 0, 0 };
if((x*x + y*y) > (2*2)) {
c = palette[i % COLORS];
}
plot(sx, sy, c);
}
printf("\n");
}
return 0;
}