forked from sol-prog/Mandelbrot_set
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmandel.cpp
104 lines (82 loc) · 3.18 KB
/
mandel.cpp
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
#include <iostream>
#include <complex>
#include <vector>
#include <chrono>
#include <functional>
#include "window.h"
#include "save_image.h"
#include "utils.h"
// clang++ -std=c++11 -stdlib=libc++ -O3 save_image.cpp utils.cpp mandel.cpp -lfreeimage
// Use an alias to simplify the use of complex type
using Complex = std::complex<double>;
// Convert a pixel coordinate to the complex domain
Complex scale(window<int> &scr, window<double> &fr, Complex c) {
Complex aux(c.real() / (double)scr.width() * fr.width() + fr.x_min(),
c.imag() / (double)scr.height() * fr.height() + fr.y_min());
return aux;
}
// Check if a point is in the set or escapes to infinity, return the number if iterations
int escape(Complex c, int iter_max, const std::function<Complex( Complex, Complex)> &func) {
Complex z(0);
int iter = 0;
while (abs(z) < 2.0 && iter < iter_max) {
z = func(z, c);
iter++;
}
return iter;
}
// Loop over each pixel from our image and check if the points associated with this pixel escape to infinity
void get_number_iterations(window<int> &scr, window<double> &fract, int iter_max, std::vector<int> &colors,
const std::function<Complex( Complex, Complex)> &func) {
int k = 0;
for(int i = scr.y_min(); i < scr.y_max(); ++i) {
for(int j = scr.x_min(); j < scr.x_max(); ++j) {
Complex c((double)j, (double)i);
c = scale(scr, fract, c);
colors[k] = escape(c, iter_max, func);
k++;
}
}
}
void fractal(window<int> &scr, window<double> &fract, int iter_max, std::vector<int> &colors,
const std::function<Complex( Complex, Complex)> &func, const char *fname, bool smooth_color) {
auto start = std::chrono::steady_clock::now();
get_number_iterations(scr, fract, iter_max, colors, func);
auto end = std::chrono::steady_clock::now();
std::cout << "Time to generate " << fname << " = " << std::chrono::duration <double, std::milli> (end - start).count() << " [ms]" << std::endl;
// Save (show) the result as an image
plot(scr, colors, iter_max, fname, smooth_color);
}
void mandelbrot() {
// Define the size of the image
window<int> scr(0, 1200, 0, 1200);
// The domain in which we test for points
window<double> fract(-2.2, 1.2, -1.7, 1.7);
// The function used to calculate the fractal
auto func = [] (Complex z, Complex c) -> Complex {return z * z + c; };
int iter_max = 500;
const char *fname = "mandelbrot.png";
bool smooth_color = true;
std::vector<int> colors(scr.size());
// Experimental zoom (bugs ?). This will modify the fract window (the domain in which we calculate the fractal function)
//zoom(1.0, -1.225, -1.22, 0.15, 0.16, fract); //Z2
fractal(scr, fract, iter_max, colors, func, fname, smooth_color);
}
void triple_mandelbrot() {
// Define the size of the image
window<int> scr(0, 1200, 0, 1200);
// The domain in which we test for points
window<double> fract(-1.5, 1.5, -1.5, 1.5);
// The function used to calculate the fractal
auto func = [] (Complex z, Complex c) -> Complex {return z * z * z + c; };
int iter_max = 500;
const char *fname = "triple_mandelbrot.png";
bool smooth_color = true;
std::vector<int> colors(scr.size());
fractal(scr, fract, iter_max, colors, func, fname, smooth_color);
}
int main() {
mandelbrot();
triple_mandelbrot();
return 0;
}