118 lines
3 KiB
C++
118 lines
3 KiB
C++
#include <cmath>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <tuple>
|
|
#include <chrono>
|
|
#include <cassert>
|
|
|
|
const int D = 2;
|
|
const int MAX_ITERATION = 200;
|
|
const double XL = - 2.5;
|
|
const double XR = 1.0;
|
|
const double YB = -1.0;
|
|
const double YT = 1.0;
|
|
extern int H;
|
|
extern int W;
|
|
extern unsigned char* RGB;
|
|
|
|
|
|
inline void dump_tga(int w, int h, unsigned char rgb[], const char *filename) {
|
|
FILE *file_unit;
|
|
unsigned char header1[12] = {0,0,2,0,0,0,0,0,0,0,0,0};
|
|
unsigned char header2[6] = {static_cast<unsigned char>(w%256),
|
|
static_cast<unsigned char>(w/256),
|
|
static_cast<unsigned char>(h%256),
|
|
static_cast<unsigned char>(h/256), 24, 0};
|
|
|
|
// Create the file.
|
|
file_unit = fopen(filename, "wb");
|
|
|
|
// Write the headers.
|
|
fwrite(header1, sizeof(unsigned char), 12, file_unit);
|
|
fwrite(header2, sizeof(unsigned char), 6, file_unit);
|
|
|
|
//Write the image data.
|
|
fwrite(rgb, sizeof(unsigned char), 3*w*h, file_unit);
|
|
|
|
// Close the file.
|
|
fclose(file_unit);
|
|
|
|
printf("Dump figure to '%s'\n", filename);
|
|
}
|
|
|
|
|
|
// Computes the value of the point (px, py), which represents the complex
|
|
// number (px + i*py), based on whether it is part of the Mandelbrot set or not
|
|
inline int escape_time(double px, double py, int n) {
|
|
// x and y represent a complex number (x + i*y)
|
|
double x = px;
|
|
double y = py;
|
|
|
|
// square both components
|
|
double x2 = x * x;
|
|
double y2 = y * y;
|
|
|
|
//// Julia set
|
|
//double cr = -0.8;
|
|
//double ci = 0.156;
|
|
|
|
// Mandelbrot set:
|
|
double cr = px;
|
|
double ci = py;
|
|
|
|
double xtmp;
|
|
|
|
// We need i (number of iteration) after the loop, so don't declare the variable inside the for.
|
|
int i;
|
|
for (i = 0; (x2 + y2) <= 4.0 && i < MAX_ITERATION; i++) {
|
|
xtmp = pow((x*x+y*y), (n/2.0))*cos(n*atan2(y,x)) + cr;
|
|
y = pow((x*x+y*y), (n/2.0))*sin(n*atan2(y,x)) + ci;
|
|
x = xtmp;
|
|
|
|
// Update our temp variables
|
|
x2 = x * x;
|
|
y2 = y * y;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
// Map a given (x, y) coordinate to the range [XL, XR] [YB, YT]
|
|
inline std::pair<double, double> scale_xy(double x, double y) {
|
|
double xx = XL + (XR - XL)/W * x;
|
|
double yy = YB + (YT - YB)/H * y;
|
|
return {xx, yy};
|
|
}
|
|
|
|
// Given an iteration, return a RGB color
|
|
// Ref: https://stackoverflow.com/questions/16500656/which-color-gradient-is-used-to-color-mandelbrot-in-wikipedia
|
|
inline std::tuple<int, int, int> get_color(int n) {
|
|
if(n < MAX_ITERATION && n) {
|
|
int i = n % 16;
|
|
const static std::vector<std::tuple<int, int, int>> colors {
|
|
{66, 30, 15},
|
|
{25, 7, 26},
|
|
{9, 1, 47},
|
|
{4, 4, 73},
|
|
{0, 7, 100},
|
|
{12, 44, 138},
|
|
{24, 82, 177},
|
|
{57, 125, 209},
|
|
{134, 181, 229},
|
|
{211, 236, 248},
|
|
{241, 233, 191},
|
|
{248, 201, 95},
|
|
{255, 170, 0},
|
|
{204, 128, 0},
|
|
{153, 87, 0},
|
|
{106, 52, 3}
|
|
};
|
|
return colors[i];
|
|
}
|
|
return {0, 0, 0};
|
|
}
|
|
|
|
|
|
std::chrono::microseconds measure_time_taskflow(unsigned);
|
|
std::chrono::microseconds measure_time_omp(unsigned);
|
|
std::chrono::microseconds measure_time_tbb(unsigned);
|