Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <SFML/Graphics/Rect.hpp>
- #include <SFML/System/Vector2.hpp>
- #include <cstdint>
- #include <complex>
- #include <functional>
- #include <vector>
- using namespace std;
- template<class T>
- class Fractal
- {
- public:
- Fractal(void);
- ~Fractal(void);
- //the most important function
- vector<uint32_t> evaluate(const sf::Rect<T>& area, const sf::Vector2u& subdivisions);
- //set the iterative function
- typedef function<void(complex<T>&)> iterative_function;
- void setIterativeFunction(iterative_function func);
- //set the domain function
- typedef function<bool(complex<T>&)> domain_function;
- void setDomainFunction(domain_function func);
- //set the maximum number of escape iterations
- void setMaxIterations(const uint32_t iterations);
- //get maximum iterations
- uint32_t getMaxIterations() const;
- //a coordinates generator
- //generates the coordinates to evaluate the fractal
- class CoordinatesGenerator
- {
- public:
- CoordinatesGenerator(const sf::Rect<T>& area, const sf::Vector2u& subdivisions);
- ~CoordinatesGenerator();
- complex<T> operator()();
- private:
- const sf::Rect<T>& area_;
- const sf::Vector2u& subdivisions_;
- complex<T> coord_;
- sf::Vector2u pixel_;
- };
- private:
- //the number of escape iterations
- uint32_t max_iterations_;
- //the tolerance where z must change
- T tolerance_;
- //the formula used for the iterative system
- iterative_function iter_function_;
- //the formula that decides either the given complex is inside or not the domain
- domain_function domain_function_;
- //returns the number of iterations that z has to do to escape
- uint32_t getIterations(complex<T> z) const;
- };
- template<class T>
- Fractal<T>::Fractal()
- {
- //setting max iterations to 1000 by default
- max_iterations_ = 1000;
- //setting standard Manderbot iterative function
- iter_function_ = iterative_function([](complex<T>& z)
- {
- z = z*z + complex<T>(1,0);
- });
- //setting standard Manderbot domain function
- domain_function_ = domain_function([](complex<T>& z)
- {
- return abs(z) < 2;
- });
- }
- // Fractal<T>::setIterativeFunction
- // iterative_function func : the function on which the system iterates
- // must match this signature : void(Complex<T>&)
- template<class T>
- void Fractal<T>::setIterativeFunction(iterative_function func)
- {
- iter_function_ = func;
- }
- // Fractal<T>::setDomainFunction
- // domain_function func : the function that determines if complex is inside domain
- // must match this signature : bool(Complex<T>&)
- template<class T>
- void Fractal<T>::setDomainFunction(domain_function func)
- {
- domain_function_ = func;
- }
- // Fractal<T>::setMaxIterations
- // iterations : set the maximum iterations for escape
- template<class T>
- void Fractal<T>::setMaxIterations(const uint32_t iterations)
- {
- max_iterations_ = iterations;
- }
- // vector<uint32_t> Fractal<T>::evaluate(const sf::Rect<T>& area, const sf::Vector2u& subdivisions)
- // area: the fractal area to evaluate
- // subdivisions : the number of subdivisions to evaluate
- // return a vector of the number of iterations
- // the vector is construction from x = 0 ... n, y = 0 ... n
- template<class T>
- vector<uint32_t> Fractal<T>::evaluate(const sf::Rect<T>& area, const sf::Vector2u& subdivisions)
- {
- uint32_t temp;
- complex<T> z(area.left,area.top);
- uint32_t num_coordinates = (subdivisions.x)*(subdivisions.y);
- vector<uint32_t> result;
- vector<complex<T>> coordinates(num_coordinates);
- CoordinatesGenerator generator(area,subdivisions);
- generate(coordinates.begin(),coordinates.end(),generator);
- for(auto& z: coordinates)
- {
- temp = getIterations(z);
- result.push_back(temp);
- }
- return result;
- }
- // uint32_t Fractal<T>::getIterations(complex<T> z) const
- // z : the complex number to evaluate
- // return the number of iterations that z escapes domain
- // using iterative and domain functions
- template<class T>
- uint32_t Fractal<T>::getIterations(complex<T> z) const
- {
- static uint32_t result;
- result = 0;
- while(domain_function_(z) && result < max_iterations_)
- {
- iter_function_(z);
- result++;
- }
- return result;
- }
- // Fractal<T>::CoordinatesGenerator::CoordinatesGenerator(const sf::Rect<T>& area, const sf::Vector2u& subdivisions)
- // area : the fractal area to evaluate
- // subdivisions : the number of subdivisions
- // used by STL algorithm
- template<class T>
- Fractal<T>::CoordinatesGenerator::CoordinatesGenerator(const sf::Rect<T>& area, const sf::Vector2u& subdivisions):
- area_(area),subdivisions_(subdivisions)
- {
- coord_ = complex<T>(area_.left,area_.top);
- pixel_.x = 0;
- pixel_.y = 0;
- }
- template<class T>
- Fractal<T>::CoordinatesGenerator::~CoordinatesGenerator()
- {
- }
- // complex<T> Fractal<T>::CoordinatesGenerator::operator()()
- // Generate coordinates to evaluate the fractal
- // used by STL algorithm
- template<class T>
- complex<T> Fractal<T>::CoordinatesGenerator::operator()()
- {
- //getting the variation of X and Y
- T deltaX = area_.width/static_cast<T>(subdivisions_.x);
- T deltaY = area_.height/static_cast<T>(subdivisions_.y);
- //creating the coordinate
- coord_ = complex<T>(static_cast<T>(pixel_.x)*deltaX + area_.left,static_cast<T>(pixel_.y)*deltaY + area_.top);
- //applying some changes to generate the next coordinate
- pixel_.x++;
- if(pixel_.x >= subdivisions_.x)
- {
- pixel_.y++;
- pixel_.x = 0;
- }
- return coord_;
- }
- template<class T>
- Fractal<T>::~Fractal()
- {
- }
- template<class T>
- uint32_t Fractal<T>::getMaxIterations() const
- {
- return max_iterations_;
- }
- vector<uint32_t>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement