How to generate random values with a uniform distibution
Hey guys,
I'm currently a little stuck with something I want to do. I want to take an object that is having its rotation updated each frame and add some noise to that rotation.
Currently I am just using Random.Range(min float, max float) to generate three values in degrees that are combined into a vector. I then use that vector to rotate the game object in the Late Update function. My question is how can I ensure that each of the three random numbers I generate are uniformly distributed?
I have seen in the documentation for random there is Random.rotationUniform however I'm not sure if i can use that as I still want to be able to specify the minimum and maximum values.
Here is an example of the code I'm using:
public GameObject rightShoulder;
private float _a;
private float _b;
private float _c;
private Vector3 _vectorA;
void LateUpdate ()
{
_a = Random.Range(-45f, 45f);
_b = Random.Range(-45f, 45f);
_c = Random.Range(-45f, 45f);
_vectorA = new Vector3 (_a, _b, _c);
rightShoulder.Transform.Rotate (_vectorA, Space.Self);
}
Hi, I don't have an answer, but a question. What do you mean by uniformly distributed?
http://en.wikipedia.org/wiki/Uniform_distribution_%28discrete%29
However I also need the mean of all the values generated over the time period be 0 or near zero.
That is not what it means. It really means, that all intervals of the same length have the same chance to be hit. Or in the discrete case: the chance of each outcome is 1/n where n is the number of possible outcomes.
On topic: Is this really not the case? Pseudo random numbers (computers can't generate real random numbers but nvm) are constructed to appear to be uniformly distributed. You can test this by adding those up:
public long n = 10000000;
private float test = 0;
for(long i = 0 ; i < n ; i++){
test += Random.Range(-45f,45f);
}
test /= n;
Debug.Log("test is " + test);
Don't do this during Update() though.
$$anonymous$$ight help if you described the problem that code gives and what you want to happen.
Because your code is officially using a uniform distribution. It will probably tend to "walk" your rotation in a direction and not even try to recenter it. That's what uniform distributions do. Like if you roll three 6's in a row -- you aren't "due" for 1's.
Use Random.rotationUniform to get the uniform rotation.
Vector3 rot = Random.rotationUniform.eulerAngles; // 0 - 360
rot = rot * 0.25f; // 0 - 90
rot = rot - Vector3.one*45; // -45 to 45
But this gives the same results as the original code (and takes a little bit longer to run and isn't as easy to tweak.) As you note, uniform rotation just rolls 0-360 three times. It's merely a typing shortcut for starting out an object with a completely arbitrary facing. It's not a special "rotation-y" way to roll dice.