UNPKG

toosoon-utils

Version:
163 lines (162 loc) 4.9 kB
import { radToSphere } from './geometry'; /** * Generate a random boolean (true or false) * * @param {number} [probability=0.5] Probability to get true * @returns {boolean} Either `true` or `false` */ export function randomBoolean(probability = 0.5) { return Math.random() < probability; } /** * Generate a random sign (1 or -1) * * @param {number} [probability=0.5] Probability to get 1 * @returns {number} Either 1 or -1 */ export function randomSign(probability = 0.5) { return randomBoolean(probability) ? 1 : -1; } /** * Generate a random floating-point number within a specified range * * @param {number} [min=0] Minimum boundary * @param {number} [max=1] Maximum boundary * @param {number} [precision=2] Number of digits after the decimal point * @returns {number} Generated float */ export function randomFloat(min = 0, max = 1, precision = 2) { return parseFloat(Math.min(min + Math.random() * (max - min), max).toFixed(precision)); } /** * Generate a random integer number within a specified range * * @param {number} min Minimum boundary * @param {number} max Maximum boundary * @returns {number} Generated integer */ export function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } /** * Generate a random hexadecimal color * * @returns {string} Generated hexadecimal color */ export function randomHexColor() { return '#' + ('00000' + ((Math.random() * (1 << 24)) | 0).toString(16)).slice(-6); } /** * Pick a random item from a given array * * @param {T[]} array Array to pick the item from * @returns {T|undefined} Random item picked */ export function randomItem(array) { if (array.length === 0) return undefined; return array[randomInt(0, array.length - 1)]; } /** * Pick a random property value from a given object * * @param {object} object Object to pick the property from * @returns {T|undefined} Random item picked */ export function randomObjectProperty(object) { const keys = Object.keys(object); const key = randomItem(keys); if (key && object.hasOwnProperty(key)) { return object[key]; } } /** * Select a random index from an array of weighted items * * @param {number[]} weights Array of weights * @returns {number} Random index based on weights */ export function randomIndex(weights) { if (weights.length === 0) return -1; let totalWeight = 0; for (let weight of weights) { totalWeight += weight; } if (totalWeight <= 0) { console.warn('randomIndex()', 'Weights must sum to > 0', totalWeight); return 0; } let weight = Math.random() * totalWeight; for (let i = 0; i < weights.length; i++) { if (weight < weights[i]) return i; weight -= weights[i]; } return 0; } /** * Generate a random number fitting a Gaussian (normal) distribution * * @param {number} [mean=0] Central value * @param {number} [spread=1] Standard deviation * @returns {number} Generated number */ export function randomGaussian(mean = 0, spread = 1) { const u = Math.random(); const v = Math.random(); const z = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v); return mean + z * spread; } // ********************* // Geometry // ********************* /** * Produce a random 2D point around the perimiter of a unit circle * * @param {number} [radius=1] Radius of the circle * @param {Point} [target] Target point * @returns {Point} Random 2D point on circle */ export function onCircle(radius = 1, target = [0, 0]) { const angle = Math.random() * 2.0 * Math.PI; target[0] = radius * Math.cos(angle); target[1] = radius * Math.sin(angle); return target; } /** * Produce a random 2D point inside a unit circle * * @param {number} [radius=1] Radius of the circle * @param {Point} [target] Target vector * @returns {Point} Random 2D point inside circle */ export function insideCircle(radius = 1, target = [0, 0]) { radius *= Math.random(); return onCircle(radius, target); } /** * Produce a random 3D point on the surface of a unit sphere * * @param {number} [radius=1] Radius of the sphere * @param {Point3} [target] Target vector * @returns {Point3} Random 3D point on sphere */ export function onSphere(radius = 1, target = [0, 0, 0]) { const u = Math.random() * Math.PI * 2; const v = Math.random() * 2 - 1; const phi = u; const theta = Math.acos(v); return radToSphere(radius, phi, theta, target); } /** * Produce a random 3D point inside a unit sphere * * @param {number} [radius=1] Radius of the sphere * @param {Point3} [target] Target vector * @returns {Point3} Random 3D point inside sphere */ export function insideSphere(radius = 1, target = [0, 0, 0]) { radius *= Math.random(); return onSphere(radius, target); }