From bd16762319f0ee6cf1948bc8885f02f75ac574d3 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Wed, 28 Dec 2011 22:50:02 +0100 Subject: [PATCH] random colours and stf output --- Attractor.hpp | 15 ++-- AttractorKernel.hpp | 21 ++--- AwesomeAttract0r.xcodeproj/project.pbxproj | 6 ++ Random.hpp | 43 ++++++++++ Tonemapper.hpp | 43 +++++----- kernels/Ikeda3D.hpp | 4 +- kernels/Logistic.hpp | 2 +- kernels/Lorenz3D.hpp | 2 +- kernels/Polynomial.hpp | 6 +- kernels/PolynomialA3D.hpp | 2 +- kernels/Unravel3D.hpp | 2 +- kernels/UnravelHeart3D.hpp | 2 +- main.cpp | 27 ++++-- stfu/stf.cpp | 8 -- stfu/stf.hpp | 6 -- stfu/stf_ext.hpp | 99 ++++++++++++++++++++++ 16 files changed, 217 insertions(+), 71 deletions(-) create mode 100644 Random.hpp create mode 100644 stfu/stf_ext.hpp diff --git a/Attractor.hpp b/Attractor.hpp index 54ad2a2..8699e76 100644 --- a/Attractor.hpp +++ b/Attractor.hpp @@ -2,6 +2,7 @@ #define ATTRACTOR_HPP #include "Logger.hpp" +#include "stfu/stf_ext.hpp" #include #include #include @@ -66,14 +67,12 @@ public: LogMoreInfo("\n"); } - stfu::node stf_output(){ - stfu::node kernel_node = kernel-> stf_output(); - stfu::node projector_node;/* = projector->stf_output();*/ - stfu::node system; - system.addChild("AttractorKernel", kernel_node); - system.addChild("Projector", projector_node); - system.addValue("Projector") = "Projector"; - return system; + stfu::node to_stf() const { + stfu::node node; + node.addChild("attractor_kernel") = stfu::to_stf(*kernel); + node.addChild("Projector"); /* = to_stf(*projector);*/ + node.addValue("Projector") = "Projector"; + return node; } friend std::ostream& operator<<(std::ostream& os, Attractor const& x); diff --git a/AttractorKernel.hpp b/AttractorKernel.hpp index 97bce4f..56ff77c 100644 --- a/AttractorKernel.hpp +++ b/AttractorKernel.hpp @@ -2,13 +2,12 @@ #define ATTRACTORKERNEL_HPP #include "Logger.hpp" +#include "stfu/stf_ext.hpp" #include #include #include #include -#include "stfu/stf.hpp" - class AttractorKernel { public: virtual ~AttractorKernel() { @@ -57,30 +56,24 @@ public: // iterate his formula, implemented by subclasses virtual void operator()() = 0; - stfu::node stf_output() { + stfu::node to_stf() const { stfu::node output; output.value("type") = type(); - { - std::stringstream dimStream; - dimStream << dimension; - output.value("dimensions") = dimStream.str(); - stf_other(output); - } + output.value("dimensions") = std::to_string(dimension); + stf_other(output); stfu::node parameters_node; for(unsigned int i = 0; i < numberOfParameters; ++i){ - std::stringstream ss; - ss << parameters[i]; - parameters_node.value(i) = ss.str(); + parameters_node.addValue() = std::to_string(parameters[i]); } output.addChild("parameters", parameters_node); return output; } - virtual std::string type() = 0; + virtual std::string type() const = 0; - virtual void stf_other(stfu::node&) {} + virtual void stf_other(stfu::node&) const {} #pragma mark - #pragma mark vector diff --git a/AwesomeAttract0r.xcodeproj/project.pbxproj b/AwesomeAttract0r.xcodeproj/project.pbxproj index 8ef2f9a..b39e32b 100644 --- a/AwesomeAttract0r.xcodeproj/project.pbxproj +++ b/AwesomeAttract0r.xcodeproj/project.pbxproj @@ -63,6 +63,9 @@ 427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = ""; }; 427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = ""; }; 427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = ""; }; + 42CEC38414AB797200C3AEDA /* Random.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Random.hpp; sourceTree = ""; }; + 42CEC38614ABB85200C3AEDA /* stf_ext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_ext.hpp; path = stfu/stf_ext.hpp; sourceTree = ""; }; + 42CEC38714ABC2C000C3AEDA /* UnravelHeart3D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = UnravelHeart3D.hpp; path = kernels/UnravelHeart3D.hpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -82,6 +85,7 @@ isa = PBXGroup; children = ( 01C5703013B63B78009D151B /* stf.hpp */, + 42CEC38614ABB85200C3AEDA /* stf_ext.hpp */, 01C5703113B63B78009D151B /* stf.cpp */, ); name = stf; @@ -93,6 +97,7 @@ 01C5700513B63AF0009D151B /* AttractorKernel.hpp */, 01C5700F13B63AF0009D151B /* AttractorKernel.cpp */, 01C5703913B63BA3009D151B /* Unravel3D.hpp */, + 42CEC38714ABC2C000C3AEDA /* UnravelHeart3D.hpp */, 01C5703A13B63BA3009D151B /* PolynomialA3D.hpp */, 01C5703B13B63BA3009D151B /* Polynomial.hpp */, 01C5703C13B63BA3009D151B /* Lorenz3D.hpp */, @@ -121,6 +126,7 @@ 427057A81475637B00CBE978 /* ImageFormatBMP.hpp */, 427057A91475637B00CBE978 /* ImageFormatPNG.hpp */, 427057AB1475637B00CBE978 /* Tonemapper.hpp */, + 42CEC38414AB797200C3AEDA /* Random.hpp */, 427057A5147562DB00CBE978 /* Projectors */, 01C5709D13B63E3A009D151B /* Kernels */, 01C5709C13B63E2F009D151B /* stf */, diff --git a/Random.hpp b/Random.hpp new file mode 100644 index 0000000..df9dada --- /dev/null +++ b/Random.hpp @@ -0,0 +1,43 @@ +// +// Random.hpp +// AwesomeAttract0r +// +// Created by Joshua Moerman on 12/28/11. +// Copyright (c) 2011 Vadovas. All rights reserved. +// + +#ifndef AwesomeAttract0r_Random_hpp +#define AwesomeAttract0r_Random_hpp + +#include + +// capital because random() was already defined :( +namespace Random { + // used as dummy paramter + struct parameters {}; + + /*! + All uniform distributions are inclusive (ie [min, max]). + */ + template + typename std::enable_if::value && !std::is_integral::value, T>::type uniform(T min, T max){ + return min + (rand() / (T) RAND_MAX) * (max - min); + } + + template + typename std::enable_if::value && std::is_integral::value, T>::type uniform(T min, T max){ + return min + (rand() % (max - min + 1)); + } + + template + std::vector make_vector(T min, T max, size_t number_of_elements){ + std::vector ret; + for (size_t i = 0; i < number_of_elements; ++i) { + ret.push_back(uniform(min, max)); + } + return ret; + } + +} // namespace random + +#endif diff --git a/Tonemapper.hpp b/Tonemapper.hpp index f2cc42d..39ee4cf 100644 --- a/Tonemapper.hpp +++ b/Tonemapper.hpp @@ -14,6 +14,9 @@ #include #include +#include "stf_ext.hpp" +#include "Random.hpp" + namespace Tonemappers { struct Normalizer { @@ -78,25 +81,15 @@ namespace Tonemappers { struct Colorizer { Colorizer(size_t n_planes) : gamma_correctors(n_planes) - , gammas() - , colors() - { - gammas[0].push_back(1.3); - gammas[1].push_back(2.0); - gammas[2].push_back(3.0); - - gammas[0].push_back(3.0); - gammas[1].push_back(1.0); - gammas[2].push_back(1.0); - - colors[0].push_back(1.5); - colors[1].push_back(2.0); - colors[2].push_back(1.0); - - colors[0].push_back(-1.0); - colors[1].push_back(-0.5); - colors[2].push_back(0.7); - } + , gammas({{std::vector(n_planes, 2.0), std::vector(n_planes, 2.0), std::vector(n_planes, 2.0)}}) + , colors({{std::vector(n_planes, 2.0), std::vector(n_planes, 2.0), std::vector(n_planes, 2.0)}}) + {} + + Colorizer(size_t n_planes, Random::parameters) + : gamma_correctors(n_planes) + , gammas({{Random::make_vector(1.0, 3.0, n_planes), Random::make_vector(1.0, 3.0, n_planes), Random::make_vector(1.0, 3.0, n_planes)}}) + , colors({{Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes)}}) + {} template void analyse(C const & canvas){ @@ -117,7 +110,6 @@ namespace Tonemappers { } } - protected: template double get_value(T const & n, size_t color) const { double ret = 0.0; @@ -129,6 +121,17 @@ namespace Tonemappers { else return 0.0; } + + stfu::node to_stf() const { + stfu::node node; + node.addValue("class") = "colorizer"; + node.addChild("gamma_matrix") = stfu::to_stf(gammas); + node.addChild("color_matrix") = stfu::to_stf(colors); + + return node; + } + + protected: std::vector gamma_correctors; std::array, 3> gammas; std::array, 3> colors; diff --git a/kernels/Ikeda3D.hpp b/kernels/Ikeda3D.hpp index 7ec072c..fdcbba8 100644 --- a/kernels/Ikeda3D.hpp +++ b/kernels/Ikeda3D.hpp @@ -20,9 +20,9 @@ public: init(); } - virtual std::string type() { return "ikeda"; }; + virtual std::string type() const { return "ikeda"; }; - virtual void generate_random_parameters() { + virtual void generate_random_parameters() { parameters[0] = rand() / double(RAND_MAX) *2.0 - 0.5; parameters[1] = rand() / double(RAND_MAX) *2.0 - 0.5; // wikipedia: u parameters[2] = rand() / double(RAND_MAX) *2.0 - 0.5; diff --git a/kernels/Logistic.hpp b/kernels/Logistic.hpp index d989697..bbab798 100644 --- a/kernels/Logistic.hpp +++ b/kernels/Logistic.hpp @@ -25,7 +25,7 @@ public: init(); } - virtual std::string type() { return "logistic"; }; + virtual std::string type() const { return "logistic"; }; virtual void generate_random_parameters() { for(unsigned int i = 0; i < numberOfParameters; ++i) { diff --git a/kernels/Lorenz3D.hpp b/kernels/Lorenz3D.hpp index a6f5447..8587b6c 100644 --- a/kernels/Lorenz3D.hpp +++ b/kernels/Lorenz3D.hpp @@ -16,7 +16,7 @@ public: init(); } - virtual std::string type() { return "lorenz"; }; + virtual std::string type() const { return "lorenz"; }; virtual void generate_random_parameters() { parameters[0] = rand() / double(RAND_MAX) * 0.02; diff --git a/kernels/Polynomial.hpp b/kernels/Polynomial.hpp index 76a41e3..626fbda 100644 --- a/kernels/Polynomial.hpp +++ b/kernels/Polynomial.hpp @@ -38,7 +38,11 @@ public: Polynomial(const unsigned int dimension, const unsigned int orde): AttractorKernel(dimension, calculateNumberOfParameters(dimension, orde)), orde(orde) {} - virtual std::string type() { return "polynomial"; }; + virtual std::string type() const { return "polynomial"; }; + + virtual void stf_other(stfu::node & node) const { + node.addValue("orde") = std::to_string(orde); + } virtual void operator()() { std::swap(vectorNew, vectorOld); diff --git a/kernels/PolynomialA3D.hpp b/kernels/PolynomialA3D.hpp index 49e232e..dd5b5cb 100644 --- a/kernels/PolynomialA3D.hpp +++ b/kernels/PolynomialA3D.hpp @@ -8,7 +8,7 @@ public: PolynomialA3D(): AttractorKernel(3, 3) {} - virtual std::string type() { return "polynomial a"; }; + virtual std::string type() const { return "polynomial a"; }; virtual void operator()() { std::swap(vectorNew, vectorOld); diff --git a/kernels/Unravel3D.hpp b/kernels/Unravel3D.hpp index fd9427c..0fe27e1 100644 --- a/kernels/Unravel3D.hpp +++ b/kernels/Unravel3D.hpp @@ -10,7 +10,7 @@ public: Unravel3D(): AttractorKernel(3, 7) {} - virtual std::string type() { return "unravel"; }; + virtual std::string type() const { return "unravel"; }; virtual void operator()() { std::swap(vectorNew, vectorOld); diff --git a/kernels/UnravelHeart3D.hpp b/kernels/UnravelHeart3D.hpp index 5ad0a77..d283a21 100644 --- a/kernels/UnravelHeart3D.hpp +++ b/kernels/UnravelHeart3D.hpp @@ -11,7 +11,7 @@ public: UnravelHeart3D(): AttractorKernel(3, 8) {} - virtual std::string type() { return "unravel heart"; }; + virtual std::string type() const { return "unravel heart"; }; virtual void operator()() { std::swap(vectorNew, vectorOld); diff --git a/main.cpp b/main.cpp index 40c29ca..3eeff1d 100644 --- a/main.cpp +++ b/main.cpp @@ -13,12 +13,16 @@ #include "Canvas.hpp" #include "Image.hpp" #include "Tonemapper.hpp" +#include "Random.hpp" + +#include "stf_ext.hpp" #include namespace po = boost::program_options; int verbose = 4; + std::string generate_filename(){ char filename[64]; time_t t = time(0); @@ -44,8 +48,9 @@ void render(Attractor & myAttractor, C & canvas, unsigned int iterations){ canvas.plot(blur, 1); } progress.show(j, iterations); - if(j == iterations/3) if(!filled(canvas, 0.01)) return; - if(j == iterations/3 * 2) if(!filled(canvas, 0.02)) return; + if(j == iterations/4) if(!filled(canvas, 0.01)) return; + if(j == iterations/4 * 2) if(!filled(canvas, 0.02)) return; + if(j == iterations/4 * 3) if(!filled(canvas, 0.03)) return; } } @@ -74,6 +79,7 @@ int main(int argc, char* argv[]) try { } std::string filename = output_path + generate_filename(); + stfu::node output; Logger logger(std::cout, LOG_VERBOSE); LayeredCanvas > canvas(width, height, 2); @@ -86,24 +92,31 @@ int main(int argc, char* argv[]) try { render(my_attractor, canvas, iterations); logger.stop(); - if(!filled(canvas, 0.05)){ + if(!filled(canvas, 0.04)){ logger.log("The canvas is too empty. Stopping."); return 0; } - std::string path(filename + ".stf"); - std::ofstream file(path.c_str()); - file << my_attractor.stf_output() << std::endl; + output = stfu::to_stf(my_attractor); } { - Tonemappers::Colorizer tonemapper(canvas.layers()); + Tonemappers::Colorizer tonemapper(canvas.layers(), Random::parameters()); tonemapper.analyse(canvas); logger.start("saving image"); ImageFormats::png::png_stream image(canvas.size<0>(), canvas.size<1>(), filename + ".png"); tonemapper.process(canvas, image); logger.stop(); + + output.addChild("tonemapper") = stfu::to_stf(tonemapper); + } + { + output.addValue("version") = __DATE__" "__TIME__; + output.addValue("notes") = "This is the version with `cheap` blur and random colours"; + std::string path(filename + ".stf"); + std::ofstream file(path.c_str()); + file << output << std::endl; } } catch (std::exception & e) { std::cout << "Terminated because of: " << e.what() << std::endl; diff --git a/stfu/stf.cpp b/stfu/stf.cpp index acb90e4..12f2f76 100644 --- a/stfu/stf.cpp +++ b/stfu/stf.cpp @@ -44,19 +44,11 @@ std::ostream& operator<< (std::ostream& out, const node& root) { return out; } -bool operator<< (const char* filename, const node& root) { - return root.write(filename); -} - std::istream& operator>> (std::istream& in, node& root) { root.read(in); return in; } -bool operator>> (const char* filename, node& root) { - return root.read(filename); -} - const std::string& node::getValue(const std::string& name, size_t index) const throw(std::out_of_range) { return get_indexed(values, name, index); } diff --git a/stfu/stf.hpp b/stfu/stf.hpp index 91f7f44..3cc91e3 100644 --- a/stfu/stf.hpp +++ b/stfu/stf.hpp @@ -56,15 +56,9 @@ class node { /** Overloaded ostream's operator<< */ friend std::ostream& operator<< (std::ostream& out, const node& root); - /** Acts like write(), but looks like this: "filename" << node */ - friend bool operator<< (const char* filename, const node& root); - /** Overloaded istream's operator>> */ friend std::istream& operator>> (std::istream& in, node& root); - /** Acts like read(), but looks like this: "filename" >> node */ - friend bool operator>> (const char* filename, node& root); - public: //@{ /** The values and children belonging to this node. To add, remove, do whatever: you CAN use these variables directly. To use indexing, use the member functions below*/ diff --git a/stfu/stf_ext.hpp b/stfu/stf_ext.hpp new file mode 100644 index 0000000..a7ae47f --- /dev/null +++ b/stfu/stf_ext.hpp @@ -0,0 +1,99 @@ +// +// stf_ext.hpp +// AwesomeAttract0r +// +// Created by Joshua Moerman on 12/28/11. +// Copyright (c) 2011 Vadovas. All rights reserved. +// + +#ifndef AwesomeAttract0r_stf_ext_hpp +#define AwesomeAttract0r_stf_ext_hpp + +#include +#include +#include +#include + +#include "stf.hpp" + +namespace std { + template + std::string to_string(T const & x){ + std::stringstream ss; + ss << x; + return ss.str(); + } +} + +namespace stfu { + + // Prototypes +#define to_stf_container_proto(x) \ + template \ + typename std::enable_if::value, node>::type to_stf(x const & array); \ + template \ + typename std::enable_if::value, node>::type to_stf(x const & array); + + to_stf_container_proto(std::vector) + to_stf_container_proto(std::list) + +#undef to_stf_container_proto + + template + typename std::enable_if::value, node>::type to_stf(std::array const & array); + template + typename std::enable_if::value, node>::type to_stf(std::array const & array); + template + node to_stf(T const & x); + + // implementations +#define to_stf_container(x) \ + template \ + typename std::enable_if::value, node>::type to_stf(x const & array) { \ + node node; \ + for (auto it = array.cbegin(); it != array.cend(); ++it){ \ + node.addValue() = std::to_string(*it); \ + } \ + return node; \ + } \ + \ + template \ + typename std::enable_if::value, node>::type to_stf(x const & array) { \ + node node; \ + for (auto it = array.cbegin(); it != array.cend(); ++it){ \ + node.addChild() = to_stf(*it); \ + } \ + return node; \ + } + + to_stf_container(std::vector) + to_stf_container(std::list) + +#undef to_stf_container + + template + typename std::enable_if::value, node>::type to_stf(std::array const & array) { + node node; + for (auto it = array.cbegin(); it != array.cend(); ++it){ + node.addValue() = std::to_string(*it); + } + return node; + } + + template + typename std::enable_if::value, node>::type to_stf(std::array const & array) { + node node; + for (auto it = array.cbegin(); it != array.cend(); ++it){ + node.addChild() = to_stf(*it); + } + return node; + } + + template + node to_stf(T const & x){ + return x.to_stf(); + } + +} // namespace stfu + +#endif