Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SFML/Graphics.hpp>
- #include <Windows.h>
- #include <string>
- #include <thread>
- #include <vector>
- #include <iostream>
- #include <complex>
- #include <chrono>
- #include <mutex>
- using std::vector;
- using std::thread;
- vector<thread> thrd;
- using std::complex;
- using std::chrono::duration_cast;
- using std::chrono::milliseconds;
- using std::cout;
- using std::endl;
- using std::ofstream;
- typedef std::chrono::steady_clock the_clock;
- bool released = false;
- int WIDTH = 1024;
- int HIGHT = 600;
- int MAX_ITERATIONS = 200;
- long double left = -2.5;
- long double right = 1.25;
- long double top = -1.2;
- long double bottom = -1.125;
- long double factor = 1;
- //double MinRe = -2.5;
- //double MaxRe = 1.25;
- //double MinIm = -1.2;
- //(-2.0, 1.0, 1.125, -1.125)
- //1024, 600
- sf::VertexArray varray(sf::Points);
- sf::Vertex vertex;
- sf::Mutex mutex, mutex2;
- //color?
- //zoom?
- //cores scatter?
- void compute_mandelbrot(double left, double right, double top, double bottom, double start, double end) //original mandelbort
- {
- //mutex.lock();
- int r = 0x00, g = 0x00, b = 0x00;
- for (int y = start; y < end; ++y)
- {
- for (int x = 0; x < WIDTH; ++x)
- {
- // Work out the point in the complex plane that
- // corresponds to this pixel in the output image.
- complex<double> c(left + (x * (right - left) / WIDTH),
- top + (y * (bottom - top) / HIGHT));
- // Start off z at (0, 0).
- complex<double> z(0.0, 0.0);
- // Iterate z = z^2 + c until z moves more than 2 units
- // away from (0, 0), or we've iterated too many times.
- int iterations = 0;
- while (abs(z) < 2.0 && iterations < MAX_ITERATIONS)
- {
- z = (z * z) + c;
- ++iterations;
- }
- if (r <= MAX_ITERATIONS)
- r = iterations;
- unsigned int colour = r | (r << 8) | (r << 16);
- vertex.color = sf::Color(r, g, b, 255);
- //vertex.color = sf::Color(6525, 1111, 222, 255);
- vertex.position = sf::Vector2f(x, y);
- mutex.lock();
- varray.append(vertex);
- mutex.unlock();
- }
- }
- //mutex.unlock();
- }
- void compute_mandelbrot2(double left, double right, double top, double bottom, double start, double end) //improved mandelbort following a tutorial
- {
- double ImageHeight = 960;
- double ImageWidth = 960;
- //double MinRe = -2.5;
- //double MaxRe = 1.25;
- //double MinIm = -1.2;
- double MinRe = left;
- double MaxRe = right;
- double MinIm = top;
- double MaxIm = MinIm + (MaxRe - MinRe)*ImageHeight / ImageWidth;
- double Re_factor = (MaxRe - MinRe) / (ImageWidth - 1);
- double Im_factor = (MaxIm - MinIm) / (ImageHeight - 1);
- //unsigned MAX_ITERATIONS = 100;
- /*int r = 0x00, g = 0x00, b = 0x00;*/
- for (unsigned y = 0; y<ImageHeight; ++y)
- {
- double c_im = MaxIm - y*Im_factor;
- for (unsigned x = 0; x<ImageWidth; ++x)
- {
- double c_re = MinRe + x*Re_factor;
- double Z_re = c_re, Z_im = c_im;
- bool isInside = true;
- for (unsigned n = 0; n<MAX_ITERATIONS; ++n)
- {
- double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
- if (Z_re2 + Z_im2 > 4)
- {
- isInside = false;
- break;
- }
- Z_im = 2 * Z_re*Z_im + c_im;
- Z_re = Z_re2 - Z_im2 + c_re;
- //unsigned int colour = r | (r << 8) | (r << 16);
- //if (n < MAX_ITERATIONS / 2)
- // vertex.color = sf::Color(0, 153, 68, 255);
- if (n > MAX_ITERATIONS / 2)
- vertex.color = sf::Color(220, 53, 168, 255);
- }
- if (isInside)
- {
- //vertex.color = sf::Color(r, g, b, 255);
- vertex.position = sf::Vector2f(x, y);
- mutex.lock();
- varray.append(vertex);
- mutex.unlock();
- }
- }
- }
- }
- void compute_mandelbrot3(double left, double right, double top, double start, double end)
- {
- double ImageHeight = 960;
- double ImageWidth = 960;
- //double MinRe = -2.5;
- //double MaxRe = 1.25;
- //double MinIm = -1.2;
- double MinRe = left;
- double MaxRe = right;
- double MinIm = top;
- double MaxIm = MinIm + (MaxRe - MinRe)*ImageHeight / ImageWidth;
- double Re_factor = (MaxRe - MinRe) / (ImageWidth - 1);
- double Im_factor = (MaxIm - MinIm) / (ImageHeight - 1);
- //unsigned MAX_ITERATIONS = 100;
- /*int r = 0x00, g = 0x00, b = 0x00;*/
- for (unsigned y = start; y<end; ++y)
- {
- double c_im = MaxIm - y*Im_factor;
- for (unsigned x = 0; x<ImageWidth; ++x)
- {
- double c_re = MinRe + x*Re_factor;
- double Z_re = c_re, Z_im = c_im;
- bool isInside = true;
- for (unsigned n = 0; n<MAX_ITERATIONS; ++n)
- {
- double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
- if (Z_re2 + Z_im2 > 4)
- {
- isInside = false;
- break;
- }
- Z_im = 2 * Z_re*Z_im + c_im;
- Z_re = Z_re2 - Z_im2 + c_re;
- //unsigned int colour = r | (r << 8) | (r << 16);
- //if (n < MAX_ITERATIONS / 2)
- // vertex.color = sf::Color(0, 153, 68, 255);
- if (n > MAX_ITERATIONS / 2)
- vertex.color = sf::Color(220, 53, 168, 255);
- }
- if (isInside)
- {
- //vertex.color = sf::Color(r, g, b, 255);
- vertex.position = sf::Vector2f(x, y);
- mutex.lock();
- varray.append(vertex);
- mutex.unlock();
- }
- }
- }
- }
- void slicer(double left, double right, double top, double bottom)
- {
- int test = -1;
- double start = 0, end = 0;
- const size_t nthreads = std::thread::hardware_concurrency(); //detect how many threads cpu has
- {
- int sliceSize = 800 / nthreads;
- std::cout << "CPU has " << nthreads << " threads" << std::endl;
- std::vector<std::thread> threads(nthreads);
- for (int t = 0; t < nthreads; t++)
- {
- threads[t] = std::thread(std::bind(
- [&]()
- {
- //std::cout << "test: " << t << "\n";
- mutex2.lock();
- test++;
- start = (test) * sliceSize;
- end = ((test + 1) * sliceSize);
- std::cout << "start: " << start << "\n";
- std::cout << "end: " << end << "\n";
- mutex2.unlock();
- compute_mandelbrot(left, right, top, bottom, start, end);
- }));
- }
- std::for_each(threads.begin(), threads.end(), [](std::thread& x) {x.join(); }); //join threads
- }
- }
- void oldSlicer(double left, double right, double top, double bottom, int slices)
- {
- int sliceSize = 960 / slices;
- double start = 0, end = 0;
- for (int i = 0; i < slices; i++)
- {
- start = i * sliceSize;
- end = ((1 + i) * sliceSize);
- //sf::Thread thread(std::bind(&compute_mandelbrot, left, right, top, bottom, start, end));
- //std::cout << "I am thread " << i+1 << std::endl;
- //thread.launch();
- //thread.wait();
- thrd.push_back(thread(compute_mandelbrot, left, right, top, bottom, start, end));
- }
- for (int i = 0; i < slices; i++)
- {
- thrd[i].join();
- }
- thrd.clear();
- compute_mandelbrot(left, right, top, bottom, 0, 800);
- }
- void handleInmput()
- {
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Z))
- {
- varray.clear();
- //left += 0.15 * factor;
- //right -= 0.1 * factor;
- //top -= 0.1 * factor;
- //bottom += 0.15 * factor;
- //factor *= 0.9349;
- //MAX_ITERATIONS += 5;
- left += 0.15 * factor;
- right -= 0.1 * factor;
- top += 0.1 * factor;
- factor *= 0.9349;
- //bottom += 0.15 * factor;
- compute_mandelbrot2(left, right, top, 1, 1, 1);
- //compute_mandelbrot2(left, right, top, 1, 1, 1);
- //MAX_ITERATIONS += 1;
- cout << "iter: " << MAX_ITERATIONS << endl;
- cout << "left: " << left << endl;
- cout << "right: " << right << endl;
- cout << "top: " << top << endl << endl;
- //the_clock::time_point start = the_clock::now();
- ////slicer((-2.0 + i), (1.0 - i), (1.125 - i), (-1.125 + i), 8); //slicer
- ////slicer((-0.751085), (-0.734975), (0.118378), (0.134488));
- ////slicer(-2.0, 1.0, 1.125, -1.125); //slicer
- ////slicer(left, right, 1.125, -1.125); //slicer
- //slicer(left, right, top, bottom); //slicer
- //the_clock::time_point end = the_clock::now();
- //auto time_taken = duration_cast<milliseconds>(end - start).count();
- //cout << "Computing the Mandelbrot set took " << time_taken << " ms." << endl;
- }
- else if (sf::Keyboard::isKeyPressed(sf::Keyboard::X)) //zoom in
- {
- left += 0.15 * factor;
- right -= 0.1 * factor;
- top += 0.1 * factor;
- factor *= 0.9349;
- cout << "iter: " << MAX_ITERATIONS << endl;
- cout << "left: " << left << endl;
- cout << "right: " << right << endl;
- cout << "top: " << top << endl << endl;
- }
- else if (sf::Keyboard::isKeyPressed(sf::Keyboard::C)) //add iterations for clarity
- {
- //the_clock::time_point start = the_clock::now();
- //compute_mandelbrot2(left, right, top, 1, 1, 1);
- //the_clock::time_point end = the_clock::now();
- //auto time_taken = duration_cast<milliseconds>(end - start).count();
- //cout << "Computing the Mandelbrot set took " << time_taken << " ms." << endl;
- MAX_ITERATIONS += 10;
- cout << "iter: " << MAX_ITERATIONS << endl;
- //sf::Keyboard::is
- }
- else if (sf::Keyboard::isKeyPressed(sf::Keyboard::V)) //set different parameters
- {
- left = -3;
- right = 1.5;
- top = -1.2;
- MAX_ITERATIONS = 20;
- //left = -0.195853;
- //right = -0.286098;
- //top = 0.336098;
- //MAX_ITERATIONS = 20;
- }
- else if (sf::Keyboard::isKeyPressed(sf::Keyboard::N))
- {
- varray.clear();
- the_clock::time_point start = the_clock::now();
- compute_mandelbrot2(left, right, top, 1, 1, 1); //without slicer
- the_clock::time_point end = the_clock::now();
- auto time_taken = duration_cast<milliseconds>(end - start).count();
- cout << "Computing the Mandelbrot set took " << time_taken << " ms." << endl;
- }
- else if (sf::Keyboard::isKeyPressed(sf::Keyboard::M))
- {
- varray.clear();
- the_clock::time_point start = the_clock::now();
- slicer(left, right, top, bottom); //with slicer
- the_clock::time_point end = the_clock::now();
- auto time_taken = duration_cast<milliseconds>(end - start).count();
- cout << "Computing the Mandelbrot set took " << time_taken << " ms." << endl;
- }
- }
- int main(int argc, char* argv[])
- {
- sf::RenderWindow window(sf::VideoMode(960, 960), "SFML-Mandelbrot");
- compute_mandelbrot2(left, right, top, 1, 1, 1);
- while (window.isOpen())
- {
- sf::Event event;
- while (window.pollEvent(event))
- {
- if (event.type == sf::Event::Closed)
- {
- window.close();
- }
- }
- handleInmput();
- window.clear();
- window.draw(varray);
- window.display();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement