diff options
author | don bright <hugh.m.bright@gmail.com> | 2013-01-28 02:42:20 (GMT) |
---|---|---|
committer | don bright <hugh.m.bright@gmail.com> | 2013-01-28 02:42:20 (GMT) |
commit | 1e64dddf1ea30282c89de7f35854a68614234652 (patch) | |
tree | 165d37c1c66f6ff79d48c74794238b3f0bed09da /src/func.cc | |
parent | 5c779159c208ca3d88c88479ab29f9cd66574859 (diff) | |
parent | d0856efe6da545693f9c50a8a2514a9f999ab5ef (diff) |
Merge branch 'master' of github.com:openscad/openscad into issue159
Diffstat (limited to 'src/func.cc')
-rw-r--r-- | src/func.cc | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/src/func.cc b/src/func.cc index 6c5f070..5dcb3e9 100644 --- a/src/func.cc +++ b/src/func.cc @@ -35,6 +35,28 @@ #include "stl-utils.h" #include "printutils.h" +/* + Random numbers + + Newer versions of boost/C++ include a non-deterministic random_device and + auto/bind()s for random function objects, but we are supporting older systems. +*/ + +#include <boost/random/mersenne_twister.hpp> +#include <boost/random/uniform_real_distribution.hpp> + +#ifdef __WIN32__ +#include <process.h> +int process_id = _getpid(); +#else +#include <sys/types.h> +#include <unistd.h> +int process_id = getpid(); +#endif + +boost::random::mt19937 deterministic_rng; +boost::random::mt19937 lessdeterministic_rng( std::time(0) + process_id ); + AbstractFunction::~AbstractFunction() { } @@ -63,9 +85,7 @@ Value Function::evaluate(const Context *ctx, { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); - if (expr) - return expr->evaluate(&c); - return Value(); + return expr ? expr->evaluate(&c) : Value(); } std::string Function::dump(const std::string &indent, const std::string &name) const @@ -121,24 +141,15 @@ Value builtin_sign(const Context *, const std::vector<std::string>&, const std:: return Value(); } -double frand() -{ - return rand()/(double(RAND_MAX)+1); -} - -double frand(double min, double max) -{ - return (min>max) ? frand()*(min-max)+max : frand()*(max-min)+min; -} - Value builtin_rands(const Context *, const std::vector<std::string>&, const std::vector<Value> &args) { + bool deterministic = false; if (args.size() == 3 && args[0].type() == Value::NUMBER && args[1].type() == Value::NUMBER && args[2].type() == Value::NUMBER) { - srand((unsigned int)time(0)); + deterministic = false; } else if (args.size() == 4 && args[0].type() == Value::NUMBER && @@ -146,16 +157,24 @@ Value builtin_rands(const Context *, const std::vector<std::string>&, const std: args[2].type() == Value::NUMBER && args[3].type() == Value::NUMBER) { - srand((unsigned int)args[3].toDouble()); + deterministic_rng.seed( (unsigned int) args[3].toDouble() ); + deterministic = true; } else { return Value(); } + double min = std::min( args[0].toDouble(), args[1].toDouble() ); + double max = std::max( args[0].toDouble(), args[1].toDouble() ); + boost::random::uniform_real_distribution<> distributor( min, max ); Value::VectorType vec; for (int i=0; i<args[2].toDouble(); i++) { - vec.push_back(Value(frand(args[0].toDouble(), args[1].toDouble()))); + if ( deterministic ) { + vec.push_back( Value( distributor( deterministic_rng ) ) ); + } else { + vec.push_back( Value( distributor( lessdeterministic_rng ) ) ); + } } return Value(vec); |