Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added quasi-random number generator and support for Rand<double>. #2149

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

paulhoux
Copy link
Collaborator

Based on the excellent article by Martin Roberts:
http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/

The QuasiRand class returns quasi random values in the range [0, 1) which are evenly distributed across the full range. When used to generate points on a sphere, it looks like this:

QuasiRandomSequencesApp 20-3-2020 15_40_28

By comparison, fully random points would look like this:

QuasiRandomSequencesApp 20-3-2020 15_40_56

The great thing about the algorithm is that it doesn't require you to know the number of values up front. Here's the same sphere after simply adding 4 times as many points:

QuasiRandomSequencesApp 20-3-2020 16_06_09

The class is templated and uses float by default, but also supports double and long double.

I will add a sample later.

Also refactored the Rand class by adding a template argument. This allows the use of double and long double random values. By default it uses float values.

…y Martin Roberts. See below for more details.

http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/

Also refactored the `Rand` class by adding a template argument. This allows the use of `double` and `long double` random values. By default it uses `float` values.
@richardeakin
Copy link
Collaborator

Really cool. And I bet you could use something like a combination of QuasiRand + Rand to create a sort of blue noise.

One thought - does it need to live in a separate file? Doesn't seem like much code, and I would think this, along with similar random number generators, could all live within cinder/Rand.h / cinder/Rand.cpp

@paulhoux
Copy link
Collaborator Author

Actually I believe this quasi-random stuff should remain in its own .h and .cpp files. It's different enough from Rand and should be a deliberate opt-in, in my opinion. I guess it's a matter of taste.

@totalgee
Copy link
Contributor

Just a side note -- I've used the very good PCG random generator (http://www.pcg-random.org or https://github.com/imneme/pcg-cpp) in Cinder projects, when I needed random generation that was fast and produced the same results (for the same seeding) on different platforms (Mac and Windows, in my case). You don't get that with the standard library (for example std::mt19937, which I believe is what ci::Rand uses). It's easy enough to use (the header) on its own, but if you're "revisiting" or adding random stuff, it might be something to think about for Cinder...e.g. as a drop-in replacement for Rand?

That said, the Martin Roberts R2 "golden ratio" noise thing is also a nice addition, thanks! (-;

//! Returns a quasi-random float in the range [0.0f,1.0f).
T nextFloat()
{
static T sIrrational = T{ 1 } / phi( 1 );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these static sIrrational (and A,B,C variations later in the file) variables should be declared const.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants