math.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /** Ensures the passed {@linkcode value} always stays between {@linkcode min} and {@linkcode max} */
  2. export function clamp(value: number, min: number, max: number) {
  3. return Math.max(Math.min(value, max), min);
  4. }
  5. /**
  6. * Transforms the value parameter from the numerical range `range1min─range1max` to the numerical range `range2min─range2max`
  7. * For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
  8. */
  9. export function mapRange(value: number, range1min: number, range1max: number, range2min: number, range2max: number) {
  10. if(Number(range1min) === 0.0 && Number(range2min) === 0.0)
  11. return value * (range2max / range1max);
  12. return (value - range1min) * ((range2max - range2min) / (range1max - range1min)) + range2min;
  13. }
  14. /** Returns a random number between {@linkcode min} and {@linkcode max} (inclusive) */
  15. export function randRange(min: number, max: number): number
  16. /** Returns a random number between 0 and {@linkcode max} (inclusive) */
  17. export function randRange(max: number): number
  18. /** Returns a random number between {@linkcode min} and {@linkcode max} (inclusive) */
  19. export function randRange(...args: number[]): number {
  20. let min: number, max: number;
  21. // using randRange(min, max)
  22. if(typeof args[0] === "number" && typeof args[1] === "number")
  23. [ min, max ] = args;
  24. // using randRange(max)
  25. else if(typeof args[0] === "number" && typeof args[1] !== "number") {
  26. min = 0;
  27. [ max ] = args;
  28. }
  29. else
  30. throw new TypeError(`Wrong parameter(s) provided - expected: "number" and "number|undefined", got: "${typeof args[0]}" and "${typeof args[1]}"`);
  31. min = Number(min);
  32. max = Number(max);
  33. if(isNaN(min) || isNaN(max))
  34. return NaN;
  35. if(min > max)
  36. throw new TypeError("Parameter \"min\" can't be bigger than \"max\"");
  37. return Math.floor(Math.random() * (max - min + 1)) + min;
  38. }
  39. /**
  40. * Generates a random ID with the specified length and radix (16 characters and hexadecimal by default)
  41. * Uses [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for better cryptographic randomness
  42. * @param length The length of the ID to generate (defaults to 16)
  43. * @param radix The [radix](https://en.wikipedia.org/wiki/Radix) of each digit (defaults to 16 which is hexadecimal. Use 2 for binary, 10 for decimal, 36 for alphanumeric, etc.)
  44. */
  45. export function randomId(length = 16, radix = 16) {
  46. const arr = new Uint8Array(length);
  47. crypto.getRandomValues(arr);
  48. return Array.from(
  49. arr,
  50. (v) => mapRange(v, 0, 255, 0, radix).toString(radix).substring(0, 1),
  51. ).join("");
  52. }