-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmandel.cpp
More file actions
202 lines (156 loc) · 4.77 KB
/
Copy pathmandel.cpp
File metadata and controls
202 lines (156 loc) · 4.77 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include "bitmap.h"
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <string.h>
#include <cstdlib>
#include <thread>
int iteration_to_color( int i, int max );
int iterations_at_point( double x, double y, int max );
void compute_image( struct bitmap *bm, double xmin, double xmax, double ymin, double ymax, int max , int no_threads );
void threaded_renderer (struct bitmap *bm, double xmin, double xmax, double ymin, double ymax, int max , int start, int end);
void show_help()
{
printf("Use: mandel [options]\n");
printf("Where options are:\n");
printf("-m <max> The maximum number of iterations per point. (default=1000)\n");
printf("-x <coord> X coordinate of image center point. (default=0)\n");
printf("-y <coord> Y coordinate of image center point. (default=0)\n");
printf("-s <scale> Scale of the image in Mandlebrot coordinates. (default=4)\n");
printf("-W <pixels> Width of the image in pixels. (default=500)\n");
printf("-H <pixels> Height of the image in pixels. (default=500)\n");
printf("-o <file> Set output file. (default=mandel.bmp)\n");
printf("-h Show this help text.\n");
printf("\nSome examples are:\n");
printf("mandel -x -0.5 -y -0.5 -s 0.2\n");
printf("mandel -x -.38 -y -.665 -s .05 -m 100\n");
printf("mandel -x 0.286932 -y 0.014287 -s .0005 -m 1000\n\n");
}
int main( int argc, char *argv[] )
{
char c;
// These are the default configuration values used
// if no command line arguments are given.
const char *outfile = "mandel.bmp";
double xcenter = 0;
double ycenter = 0;
double scale = 4;
int image_width = 500;
int image_height = 500;
int max = 1000;
int no_threads = 1;
// For each command line argument given,
// override the appropriate configuration value.
while((c = getopt(argc,argv,"x:y:s:W:H:m:n:o:h"))!=-1) {
switch(c) {
case 'x':
xcenter = atof(optarg);
break;
case 'y':
ycenter = atof(optarg);
break;
case 's':
scale = atof(optarg);
break;
case 'n':
no_threads = atoi(optarg);
break;
case 'W':
image_width = atoi(optarg);
break;
case 'H':
image_height = atoi(optarg);
break;
case 'm':
max = atoi(optarg);
break;
case 'o':
outfile = optarg;
break;
case 'h':
show_help();
exit(1);
break;
}
}
// Display the configuration of the image.
printf("mandel: x=%lf y=%lf scale=%lf max=%d no_threads=%d outfile=%s\n",xcenter,ycenter,scale,max,no_threads,outfile);
// Create a bitmap of the appropriate size.
struct bitmap *bm = bitmap_create(image_width,image_height);
// Fill it with a dark blue, for debugging
bitmap_reset(bm,MAKE_RGBA(0,0,255,0));
// Compute the Mandelbrot image
compute_image(bm,xcenter-scale,xcenter+scale,ycenter-scale,ycenter+scale,max , no_threads);
// Save the image in the stated file.
if(!bitmap_save(bm,outfile)) {
fprintf(stderr,"mandel: couldn't write to %s: %s\n",outfile,strerror(errno));
return 1;
}
return 0;
}
/*
Compute an entire Mandelbrot image, writing each point to the given bitmap.
Scale the image to the range (xmin-xmax,ymin-ymax), limiting iterations to "max"
*/
void compute_image( struct bitmap *bm, double xmin, double xmax, double ymin, double ymax, int max , int no_threads)
{
int i;
std::thread thread_list[no_threads];
for(i = 0; i< no_threads ; i++)
{
int start = i*(bitmap_height(bm)/no_threads);
int end = start + (bitmap_height(bm)/no_threads);
thread_list[i] = std::thread(threaded_renderer, bm, xmin, xmax, ymin, ymax, max , start, end );
}
for(i = 0; i< no_threads ; i++)
{
thread_list[i].join();
}
}
/*
Return the number of iterations at point x, y
in the Mandelbrot space, up to a maximum of max.
*/
int iterations_at_point( double x, double y, int max )
{
double x0 = x;
double y0 = y;
int iter = 0;
while( (x*x + y*y <= 4) && iter < max ) {
double xt = x*x - y*y + x0;
double yt = 2*x*y + y0;
x = xt;
y = yt;
iter++;
}
return iteration_to_color(iter,max);
}
/*
Convert a iteration number to an RGBA color.
Here, we just scale to gray with a maximum of imax.
Modify this function to make more interesting colors.
*/
int iteration_to_color( int i, int max )
{
int gray = 255*i/max;
return MAKE_RGBA(gray,gray,gray,0);
}
void threaded_renderer(struct bitmap *bm, double xmin, double xmax, double ymin, double ymax, int max , int start, int end)
{
int i,j;
int width = bitmap_width(bm);
int height = bitmap_height(bm);
for(j=start;j<end;j++) {
for(i=0;i<width;i++) {
// Determine the point in x,y space for that pixel.
double x = xmin + i*(xmax-xmin)/width;
double y = ymin + j*(ymax-ymin)/height;
// Compute the iterations at that point.
int iters = iterations_at_point(x,y,max);
// Set the pixel in the bitmap.
bitmap_set(bm,i,j,iters);
}
}
}