Open main menu

CDOT Wiki β

Changes

BETTERRED

3,524 bytes added, 13:27, 12 April 2017
Assignment 1 - Select and Assess
The program can then be executed by running the compiled binary and it will display the time it took to generate the Mandelbrot set and save the pictures.
 
{| class="wikitable mw-collapsible mw-collapsed"
! Mandelbrot CPU( ... )
|-
|
<syntaxhighlight lang="cpp">
#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<float>;
 
// Convert a pixel coordinate to the complex domain
Complex scale(window<int> &scr, window<float> &fr, Complex c) {
Complex aux(c.real() / (float)scr.width() * fr.width() + fr.x_min(),
c.imag() / (float)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<float> &fract, int iter_max, std::vector<int> &colors,
const std::function<Complex( Complex, Complex)> &func) {
int k = 0, progress = -1;
for(int i = scr.y_min(); i < scr.y_max(); ++i) {
for(int j = scr.x_min(); j < scr.x_max(); ++j) {
Complex c((float)j, (float)i);
c = scale(scr, fract, c);
colors[k] = escape(c, iter_max, func);
k++;
}
if(progress < (int)(i*100.0/scr.y_max())){
progress = (int)(i*100.0/scr.y_max());
std::cout << progress << "%\n";
}
}
}
 
void fractal(window<int> &scr, window<float> &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 <float, 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, 1000, 0, 1000);
// The domain in which we test for points
window<float> 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, 2000, 0, 2000);
// The domain in which we test for points
window<float> 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;
}
 
</syntaxhighlight>
|}
=== Observations ===
17
edits