Advertisement
Firzen_

Untitled

Nov 18th, 2013
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.26 KB | None | 0 0
  1.     public class RandomDistribution
  2.     {
  3.         Vector2 _range;
  4.         Random _random;
  5.         float _widthModifier;
  6.         float _heightModifier;
  7.  
  8.         /* So here is the theory behind this. WARNING: calculus
  9.          *
  10.          * So we want to have some decent distribution of values
  11.          * so that stuff is more likely to spawn in the center than on the sides.
  12.          *
  13.          * For that and simplicities sake we choose f(x)=1/(x^2+1)
  14.          * Now we need to bring this distribution into a form where we can actually get a RANDOM value from that range.
  15.          *
  16.          * So we need to integrate this function, since we need to know how much of the randomness has been "used up" already
  17.          * With that we end up with F(x)=atan(x)
  18.          *
  19.          * So next we need to map the values from 0 to 1 that the RANDOM class gives us to that.
  20.          * So we take the inverse function of tan which is fortunately tan, hence this solution is simple and fast enough to use.
  21.          */
  22.  
  23.         public RandomDistribution (Vector2 range, float steepness, int randomSeed=0)
  24.         {
  25.             if (steepness <= 0 || steepness >= 1)
  26.                 throw new ArgumentException("Steepness must be inbetween 0 and 1");
  27.             if (range.X > range.Y)
  28.                 throw new ArgumentException("range.X must not be greater than range.Y");
  29.  
  30.             _random = randomSeed != 0 ? new Random(randomSeed) : Chunk.RANDOM;
  31.             _range = range;
  32.  
  33.             //This defines how steep the values change in the end
  34.             _widthModifier = (float)Math.PI * steepness /2;
  35.             //This is to make sure our values are in a sensible range
  36.             _heightModifier = (float)Math.Tan(_widthModifier)*2;
  37.         }
  38.  
  39.         public float GetNext()
  40.         {
  41.             //[0,1]->[-1,1]
  42.             double randomBetweenMinusOneAndOne = _random.NextDouble() * 2 - 1;
  43.             //[-1,1]->[-_widthModifier,widthModifier]->[-0.5f,0.5f]
  44.             double distributedValue = Math.Tan( randomBetweenMinusOneAndOne* _widthModifier)/_heightModifier;
  45.             //[-0.5f,0.5f]->[0,1]
  46.             double normalizedValue = distributedValue+0.5f;
  47.             return (float)(_range.X + normalizedValue * (_range.Y - _range.X));
  48.         }
  49.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement