Browse Source

random colours and stf output

master
Joshua Moerman 13 years ago
parent
commit
bd16762319
  1. 15
      Attractor.hpp
  2. 21
      AttractorKernel.hpp
  3. 6
      AwesomeAttract0r.xcodeproj/project.pbxproj
  4. 43
      Random.hpp
  5. 43
      Tonemapper.hpp
  6. 4
      kernels/Ikeda3D.hpp
  7. 2
      kernels/Logistic.hpp
  8. 2
      kernels/Lorenz3D.hpp
  9. 6
      kernels/Polynomial.hpp
  10. 2
      kernels/PolynomialA3D.hpp
  11. 2
      kernels/Unravel3D.hpp
  12. 2
      kernels/UnravelHeart3D.hpp
  13. 27
      main.cpp
  14. 8
      stfu/stf.cpp
  15. 6
      stfu/stf.hpp
  16. 99
      stfu/stf_ext.hpp

15
Attractor.hpp

@ -2,6 +2,7 @@
#define ATTRACTOR_HPP
#include "Logger.hpp"
#include "stfu/stf_ext.hpp"
#include <iostream>
#include <fstream>
#include <string>
@ -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);

21
AttractorKernel.hpp

@ -2,13 +2,12 @@
#define ATTRACTORKERNEL_HPP
#include "Logger.hpp"
#include "stfu/stf_ext.hpp"
#include <string>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#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

6
AwesomeAttract0r.xcodeproj/project.pbxproj

@ -63,6 +63,9 @@
427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = "<group>"; };
427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = "<group>"; };
427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
42CEC38414AB797200C3AEDA /* Random.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Random.hpp; sourceTree = "<group>"; };
42CEC38614ABB85200C3AEDA /* stf_ext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_ext.hpp; path = stfu/stf_ext.hpp; sourceTree = "<group>"; };
42CEC38714ABC2C000C3AEDA /* UnravelHeart3D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = UnravelHeart3D.hpp; path = kernels/UnravelHeart3D.hpp; sourceTree = "<group>"; };
/* 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 */,

43
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 <vector>
// capital because random() was already defined :(
namespace Random {
// used as dummy paramter
struct parameters {};
/*!
All uniform distributions are inclusive (ie [min, max]).
*/
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value && !std::is_integral<T>::value, T>::type uniform(T min, T max){
return min + (rand() / (T) RAND_MAX) * (max - min);
}
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value && std::is_integral<T>::value, T>::type uniform(T min, T max){
return min + (rand() % (max - min + 1));
}
template <typename T>
std::vector<T> make_vector(T min, T max, size_t number_of_elements){
std::vector<T> ret;
for (size_t i = 0; i < number_of_elements; ++i) {
ret.push_back(uniform(min, max));
}
return ret;
}
} // namespace random
#endif

43
Tonemapper.hpp

@ -14,6 +14,9 @@
#include <cmath>
#include <array>
#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<double>(n_planes, 2.0), std::vector<double>(n_planes, 2.0), std::vector<double>(n_planes, 2.0)}})
, colors({{std::vector<double>(n_planes, 2.0), std::vector<double>(n_planes, 2.0), std::vector<double>(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 <typename C>
void analyse(C const & canvas){
@ -117,7 +110,6 @@ namespace Tonemappers {
}
}
protected:
template <typename T>
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<GammaCorrector> gamma_correctors;
std::array<std::vector<double>, 3> gammas;
std::array<std::vector<double>, 3> colors;

4
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;

2
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) {

2
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;

6
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);

2
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);

2
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);

2
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);

27
main.cpp

@ -13,12 +13,16 @@
#include "Canvas.hpp"
#include "Image.hpp"
#include "Tonemapper.hpp"
#include "Random.hpp"
#include "stf_ext.hpp"
#include <boost/program_options.hpp>
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<Canvas2D<unsigned int> > 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;

8
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<std::string, std::string>(values, name, index);
}

6
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*/

99
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 <sstream>
#include <list>
#include <vector>
#include <array>
#include "stf.hpp"
namespace std {
template <typename T>
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 T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array); \
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array);
to_stf_container_proto(std::vector)
to_stf_container_proto(std::list)
#undef to_stf_container_proto
template <typename T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T>
node to_stf(T const & x);
// implementations
#define to_stf_container(x) \
template <typename T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array) { \
node node; \
for (auto it = array.cbegin(); it != array.cend(); ++it){ \
node.addValue() = std::to_string(*it); \
} \
return node; \
} \
\
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> 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 T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addValue() = std::to_string(*it);
}
return node;
}
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addChild() = to_stf(*it);
}
return node;
}
template <typename T>
node to_stf(T const & x){
return x.to_stf();
}
} // namespace stfu
#endif