Rotate a random number into deterministic white noise

I need to be able to generate one random number and then use that number to seed a theoretically infinite 2d plane on the fly with booleans. I need a function that I can call deterministic with three inputs (x, y and a random seed) and returns a pseudo-random result back:

int r = random()
//...
var value_for_point = f(x,y,r);

      

If I were to use this function to fill a 10x10 array with ones and zeros, it would ideally look the same as / if I asked for a random value for each cell as I walked, i.e. white noise. It doesn't have to be perfect - its not for statistical analysis. I just need to be able to recreate an array with the same random number.

I can't just seed the random number generator for two reasons. First, I need this function to be x and y based. I can call this function to fill an array between (0,0) and (10, 10) and then ask for values ​​between (-10, -5) and (3,4). Secondly, the language I am using does not have a seed function.

I'm sure there is either a trivial way to do this, which I can't see, or something inside the fractal area that might help me. Does anyone know how to do this?

+2


source to share


6 answers


I think you want Perlin noise ?



+2


source


It's not 100% perfect, but what about using a canned algorithm like SHA1 or MD5? SHA1 produces a 160 bit string from any character string and more or less random. To fill your 10x10 boolean array, you only need the least significant 100 bits, which should be close to random. Since you start with a known base string (any length) as a seed, your values ​​are reproducible.



I don't know which language you are using, but SHA1 and MD5 implementations are available for almost every operating system.

+1


source


Very simple mathematical algorithms can produce very complex deterministic inference. Take a look at the tungsten book .

You can, for example, use rule 30 to generate this.

+1


source


Help if we knew the language.

FROM#...

static bool GetPixel(int seed, ushort x, ushort y)
{
    int randomSeed = (x << 16 | y) ^ seed;
    Random rnd = new Random(randomSeed); 
    /* if you just want a constant result you can seed the function 
       on app start and never touch the random generator again */
    return rnd.NextDouble() >= .5;
}

      

0


source


Just use something simple like

private static uint GetUint()
{
    m_z = 36969 * (m_z & 65535) + (m_z >> 16);
    m_w = 18000 * (m_w & 65535) + (m_w >> 16);
    return (m_z << 16) + m_w;
}

      

and run the initial values ​​m_z and m_w. Do this for each, x and y.

0


source


You cannot simulate an infinitely large plane. Ultimately, you are stuck with a random number generator, and there is always a limit to the number of bits of state your generator can store.

However, the limitation is mostly theoretical. For most practical purposes, you can limit the size of the plane based on the size that the user can specify. For example, if x and y are two 32-bit integers, then you only need to simulate a plane that 2 ^ 32-1x2 ^ 32-1 is a long way to infinity.

Considering what you said about the random number generator in your system, most likely you will need (or at least really want to) write your own generator, or use an existing one on the Internet for a fairly long period. If you are going to use 32 bits for your X and Y coordinates, you need a generator with at least a 64 bit period.

From there, it's pretty simple: you concatenate bits of x, y coordinates, for example, create a linear address into any other 2D array, then use the result as seed for a PRNG and get the result.

0


source







All Articles