I need a pseudo random number generator that gives me a number from the range [-1, 1] (range is optional) from two inputs of the type float.
I'll also try to explain why I need it:
I'm using the Diamond-Square algorithm to create a height map for my terrain engine. The terrain is split into patches (Chunked LOD).
The problem with Diamond-Square is that it uses the random function, so let's say two neighbor patches are sharing same point (x, z) then I want the height to be the same for them all so that I won't get some crack effect.
Some may say I could fetch the height information from the neighbor patch, but then the result could be different after which patch was created first.
So that's why I need a pseudo number generator that returns an unique number given two inputs which are the (x, z).
(I'm not asking someone to write such function, I just need a general feedback and or known algorithms that do something similar).
Random Number Generator (Pseudocode)RANDOM(Integer1 : INTEGER, Integer2 : INTEGER) RETURNS INTEGER generates a random integer in the range from Integer1 to Integer2 inclusive.
The pseudorandom generators used in cryptography and universal algorithmic derandomization have not been proven to exist, although their existence is widely believed. Proofs for their existence would imply proofs of lower bounds on the circuit complexity of certain explicit functions.
random — Generate pseudo-random numbers — Python 3.11.0 documentation.
The Excel RAND and RANDBETWEEN functions generate pseudo-random numbers from the Uniform distribution, aka rectangular distribution, where there is equal probability for all values that a random variable can take on.
You need something similar to a hash function on the pair (x, z)
.
I would suggest something like
(a * x + b * z + c) ^ d
where all numbers are integers, a
and b
are big primes so that the integer multiplications overflow, and c
and d
are some random integers. ^
is bitwise exclusive or. The result is a random integer which you can scale to the desired range.
This assumes that the map is not used in a game where knowing the terrain is of substantial value, as such a function is not secure for keeping it a secret. In that case you'd better use some cryptographic function.
If you're looking for a bijection from IRxIR -> [-1;1], I can suggest this:
First let's find a bijection from IR-> ]-1;1[ so we just need to find a bijection from IRxIR->IR
tan(x): ]-Pi/2;Pi/2[ -> IR
arctan(x) : IR -> ]-Pi/2;Pi/2[
1/Pi*arctan(x) + 1/2: IR -> ]0;1[
2*arctan(x) : IR->]-Pi:Pi[
and
ln(x) : IR + -> IR
exp(x): IR -> R+
let's write:
(x,y) in ]0,1[ x ]0,1[
x= 0,x1x2x3x4...xn...etc where x1x2x3x4...xn represent the decimals of x in base 10
y=0,y1y2y3y4...ym...etc idem
Let's define z=0,x1y1x2y2xx3y3....xnyn...Oym in ]0,1[
Then by construction we can provethere that it is exact bijection from ]0,1[ x ]0,1[ to ]0,1[. (i'm not sure it's is true for number zith infinite decimals..but it's at least a "very good" injection, tell me if i'm wrong)
let's name this function : CANTOR(x,y)
then 2*CANTOR-1 is a bijection from ]0,1[ x ]0,1[ -> ]-1,1[
here you go, you get the bijection from IRxIR -> ]-1;1[...
You can combine with a bijection from IR-> ]0,1[
IRxIR -> ]-1;1[
(x,y) -> 2*CANTOR(1/Pi*arctan(x) + 1/2,1/Pi*arctan(y) + 1/2)-1
let's define the reciproque, we process the same way:
RCANTOR: z -> (x,y) (reciproque of CANTOR(x,y)
RCANTOR((z+1)/2): ]-1:1[ -> ]01[x ]0,1[
then 1/Pi*tan(RCANTOR((z+1)/2)) + 1/2 : z ->(x,y)
]-1;1[ -> IRxIR
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With