mirror of https://github.com/vitalif/openscad
commit
2e65c6ddc5
47
src/func.cc
47
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()
|
||||
{
|
||||
}
|
||||
|
@ -119,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 &&
|
||||
|
@ -144,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);
|
||||
|
|
Loading…
Reference in New Issue