summaryrefslogtreecommitdiff
path: root/src/func.cc
diff options
context:
space:
mode:
authordon bright <hugh.m.bright@gmail.com>2013-01-28 02:42:20 (GMT)
committerdon bright <hugh.m.bright@gmail.com>2013-01-28 02:42:20 (GMT)
commit1e64dddf1ea30282c89de7f35854a68614234652 (patch)
tree165d37c1c66f6ff79d48c74794238b3f0bed09da /src/func.cc
parent5c779159c208ca3d88c88479ab29f9cd66574859 (diff)
parentd0856efe6da545693f9c50a8a2514a9f999ab5ef (diff)
Merge branch 'master' of github.com:openscad/openscad into issue159
Diffstat (limited to 'src/func.cc')
-rw-r--r--src/func.cc51
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);
contact: Jan Huwald // Impressum