#include #include #include #include #include #include #include #include #include "functions.hpp" #include "Fractal.hpp" const double DOMAIN_X_MIN = -2.0; const double DOMAIN_X_MAX = 2.0; const double DOMAIN_Y_MIN = -1.7; const double DOMAIN_Y_MAX = 1.7; const int IMAGE_WIDTH = 1920; const int IMAGE_HEIGHT = 1080; const int FRAMERATE = 20; int main(int argc, char **argv) { boost::program_options::options_description po ("Mandelbrot"); po.add_options() ("help", "Help") ("noratio", "Don't force the window ratio on domain") ("framerate", boost::program_options::value()->default_value(FRAMERATE), "Framerate") ("width", boost::program_options::value()->default_value(IMAGE_WIDTH), "Window width") ("height", boost::program_options::value()->default_value(IMAGE_HEIGHT), "Window height") ("domXmin", boost::program_options::value()->default_value(DOMAIN_X_MIN), "Domain X (Min)") ("domXmax", boost::program_options::value()->default_value(DOMAIN_X_MAX), "Domain X (Max)") ("domYmin", boost::program_options::value()->default_value(DOMAIN_Y_MIN), "Domain Y (Min)") ("domYmax", boost::program_options::value()->default_value(DOMAIN_Y_MAX), "Domain Y (Max)") ("filename", boost::program_options::value(), "Filename") ; boost::program_options::variables_map vm; boost::program_options::store(boost::program_options::parse_command_line(argc, argv, po), vm); boost::program_options::notify(vm); if (vm.count("help")) { std::cout << po << std::endl; return 0; } int screen_width = vm["width"].as(); int screen_height = vm["height"].as(); double windowRatio = (double)screen_width / (double)screen_height; Fractal mandelbrot( screen_width, screen_height, Domain( vm["domXmin"].as(), vm["domXmax"].as(), vm["domYmin"].as(), vm["domYmax"].as() ) ); if(!vm.count("noratio")){ std::cerr << "Force ratio " << windowRatio << std::endl; mandelbrot.getDomain().setRatio(windowRatio); } if(vm.count("filename")) { mandelbrot.getFrame().saveToFile(vm["filename"].as()); std::cerr << "Screenshot stored in file " << vm["filename"].as() << std::endl; return 0; } sf::RenderWindow window(sf::VideoMode(screen_width, screen_height), "Mandelbrot"); window.setFramerateLimit(vm["framerate"].as()); sf::Texture texture; sf::Sprite sprite; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { switch (event.type) { case sf::Event::Closed: window.close(); break; case sf::Event::MouseButtonReleased: { sf::Vector2i mousePosition = sf::Mouse::getPosition(window); switch (event.mouseButton.button) { case sf::Mouse::Left: mandelbrot.moveTo(mousePosition.x, mousePosition.y); break; case sf::Mouse::Right: mandelbrot.moveTo(mousePosition.x, mousePosition.y); break; default: break; } } break; case sf::Event::MouseWheelMoved: if(event.mouseWheel.delta > 0) { mandelbrot.zoom(1.05); } else { mandelbrot.zoom(1.05, true); } break; case sf::Event::KeyPressed: switch (event.key.code) { case sf::Keyboard::Escape: window.close(); break; case sf::Keyboard::Key::Add: mandelbrot.zoom(1.5); break; case sf::Keyboard::Key::Subtract: mandelbrot.zoom(1.5, true); break; case sf::Keyboard::Key::Right: mandelbrot.moveBy(0.01, 0); break; case sf::Keyboard::Key::Left: mandelbrot.moveBy(-0.01, 0); break; case sf::Keyboard::Key::Up: mandelbrot.moveBy(0, -0.01); break; case sf::Keyboard::Key::Down: mandelbrot.moveBy(0, 0.01); break; case sf::Keyboard::Key::S: { std::time_t t = std::time(nullptr); std::tm tm = *std::localtime(&t); std::stringstream filename; filename << "Screenshot_" << std::put_time(&tm, "%Y%m%d%H%M%S") << ".jpeg"; mandelbrot.getFrame().saveToFile(filename.str()); std::cerr << "Screenshot stored in file " << filename.str() << std::endl; } break; case sf::Keyboard::Key::D: { std::cerr << std::scientific << std::setprecision(10) << "domXmin=" << mandelbrot.getDomain().x_min << ", domXmax=" << mandelbrot.getDomain().x_max << ", domYmin=" << mandelbrot.getDomain().y_min << ", domYmax=" << mandelbrot.getDomain().y_max << std::endl; } break; // Renderer selection case sf::Keyboard::Key::Q: std::cerr << "Selected smooth renderer" << std::endl; mandelbrot.setRenderFunction(render_smooth); break; case sf::Keyboard::Key::W: std::cerr << "Selected linear renderer" << std::endl; mandelbrot.setRenderFunction(render_linear); break; case sf::Keyboard::Key::E: std::cerr << "Selected black&white renderer" << std::endl; mandelbrot.setRenderFunction(render_black_and_white); break; case sf::Keyboard::Key::R: std::cerr << "Selected green gradient renderer" << std::endl; mandelbrot.setRenderFunction(render_green_gradient); break; // Fractal selection case sf::Keyboard::Key::Num1: std::cerr << "Selected mandelbrot algorithm" << std::endl; mandelbrot.setFractalFunction(fractal_mandelbrot); break; case sf::Keyboard::Key::Num2: std::cerr << "Selected triple mandelbrot algorithm" << std::endl; mandelbrot.setFractalFunction(fractal_triple_mandelbrot); break; case sf::Keyboard::Key::Num3: std::cerr << "Selected quadruple mandelbrot algorithm" << std::endl; mandelbrot.setFractalFunction(fractal_quadruple_mandelbrot); break; case sf::Keyboard::Key::Num4: std::cerr << "Selected quintuple mandelbrot algorithm" << std::endl; mandelbrot.setFractalFunction(fractal_quintuple_mandelbrot); break; default: break; } default: break; } } window.clear(sf::Color::Black); texture.loadFromImage(mandelbrot.getFrame()); sprite.setTexture(texture); window.draw(sprite); window.display(); } return 0; }