8

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).

starblue
  • 55,348
  • 14
  • 97
  • 151
Jón Trausti Arason
  • 4,548
  • 1
  • 39
  • 46
  • I didn't quite understand the question. How do you define a random number that's based on two numbers? If it's random, it's random, and the only factor to worry about is the seed and the distribution. The seed can be any combination of those two input numbers, if that's what you're aiming for. But the result would still be completely random. Please clarify your expectations the numbers you're trying to generate. – Assaf Lavie Jun 24 '11 at 15:26
  • It shouldn't be random, I'm just saying the Diamond-Square gets a random number. I'm asking for an unique number for given x, z or in other words some pseudo number generator given the two inputs. The random tag on this question is rather confusing and I should remove it. I'm not asking anyone to write a function for me, but I'd love to get some feedback, direction or known algorithms that do it. Thanks! – Jón Trausti Arason Jun 24 '11 at 15:36

3 Answers3

6

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.

starblue
  • 55,348
  • 14
  • 97
  • 151
2

If you're looking for a bijection from IRxIR -> [-1;1], I can suggest this:

bijection from IR to ]-a:a[

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+

Bijection from ]0,1[ x ]0,1[ -> ]0,1[

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[

Then combining all the above assertions:

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
Ricky Bobby
  • 7,490
  • 7
  • 46
  • 63
0

Just pick any old hash function, stick in the binary description of the coordinates and use the output.

Mikola
  • 9,176
  • 2
  • 34
  • 41