Repository: motion-canvas/motion-canvas
File: packages/core/src/scenes/Random.ts (TypeScript)

Code before:
    }

    return value;
  }

  // This is an optimization.
  // Since gauss() generates a pair of independent Gaussian random numbers,
  // it returns one immediately and stores the other for the next call to gauss().
  private nextGauss: number | null = null;

  /**
   * Get a random float from a gaussian distribution.
   * @param mean - The mean of the distribution.
   * @param stdev - The standard deviation of the distribution.
   */
  public gauss(mean = 0.0, stdev = 1.0): number {
    let z = this.nextGauss;
    this.nextGauss = null;
    if (z === null) {
      const x2pi = this.next() * 2 * Math.PI;
      const g2rad = Math.sqrt(-2.0 * Math.log(1.0 - this.next()));
      z = Math.cos(x2pi) * g2rad;
      this.nextGauss = Math.sin(x2pi) * g2rad;
    }
    return mean + z * stdev;
  }

  /**
   * Get an array filled with random floats in the given range.
   *
   * @param size - The size of the array.
   * @param from - The start of the range.
   * @param to - The end of the range.
   */
  public floatArray(size: number, from = 0, to = 1): number[] {
    return range(size).map(() => this.nextFloat(from, to));
  }

  /**
   Get an array filled with random integers in the given range.
   *
   * @param size - The size of the array.
   * @param from - The start of the range.
   * @param to - The end of the range. Exclusive.
   */
  public intArray(size: number, from = 0, to = 4294967296): number[] {
    return range(size).map(() => this.nextInt(from, to));
  }

  /**
   * Create a new independent generator.

Review comment (suggestion):
For reference, this is Python's implementation:

```python
def gauss(self, mu=0.0, sigma=1.0):
  random = self.random
  z = self.gauss_next
  self.gauss_next = None
  if z is None:
      x2pi = random() * TWOPI
      g2rad = _sqrt(-2.0 * _log(1.0 - random()))
      z = _cos(x2pi) * g2rad
      self.gauss_next = _sin(x2pi) * g2rad

  return mu + z * sigma
```

Code after:

  /**
   * Get the next random integer in the given range.
   *
   * @param from - The start of the range.
   * @param to - The end of the range. Exclusive.
   */
  public nextInt(from = 0, to = 4294967296) {
    let value = Math.floor(map(from, to, this.next()));
    if (value === to) {
      value = from;
    }

    return value;
  }

  /**
   * Get a random float from a gaussian distribution.
   * @param mean - The mean of the distribution.
   * @param stdev - The standard deviation of the distribution.
   */
  public gauss(mean = 0, stdev = 1): number {
    let z = this.nextGauss;
    this.nextGauss = null;
    if (z === null) {
      const x2pi = this.next() * 2 * Math.PI;
      const g2rad = Math.sqrt(-2 * Math.log(1 - this.next()));
      z = Math.cos(x2pi) * g2rad;
      this.nextGauss = Math.sin(x2pi) * g2rad;
    }
    return mean + z * stdev;
  }

  /**
   * Get an array filled with random floats in the given range.
   *
   * @param size - The size of the array.
   * @param from - The start of the range.
   * @param to - The end of the range.
   */
  public floatArray(size: number, from = 0, to = 1): number[] {
    return range(size).map(() => this.nextFloat(from, to));
  }

  /**
   Get an array filled with random integers in the given range.
   *
   * @param size - The size of the array.
   * @param from - The start of the range.
   * @param to - The end of the range. Exclusive.
   */