Parse
File Parse random.js
This tree is parsed live from the source file.
Classes
-
{{ item.name }}
- {{ key }}
Not Classes
{{ getTree() }}
Comments
{{ getTreeComments() }}
Source
/*
title: Random
---
The _random_ class provides a range of methods for producing random values.
The `random` object is instansiated for free:
const random = new Random()
// examples
random.int()
random.point()
*/
class Random {
/* The minimum value the _point(value)_ can be, before
the automatic 'float' method is used over the 'int' method.
*/
pointIntMin = 2
int(min=1, max) {
/* Generate an integer between 0 and the given min.
Given 1 (default), the result will be either 0 or 1
random.int(10)
7
random.int(50)
30
random.int(300)
220
*/
if(max != undefined) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
let r = this.float()
return Number( ~~(r * min) )
}
float(min=1, max) {
/* Generate a decimal number between `0` and `1`.
Provide a min/max to limit
random.float()
random.float(.2, 1)
*/
if(max != undefined) {
return Math.random() * (max - min) + min;
}
return Math.random() * min
}
callOne(functions) {
/* Given many functions, call one. */
return selections[this.index(selections)]()
}
choice(selections) {
/* Give many items, return one */
return selections[this.index(selections)]
}
index(selections) {
/* Given many, return an index */
return Math.floor(selections.length * Math.random())
}
string(multiplier=1, rot=32){
/* Return a random string */
return this.radix(this.float(multiplier), rot).slice(2)
}
radix(v, rot=32) {
return v.toString(rot)
}
point(multiplier=1, method=undefined) {
/*
return a random point(), with the X/Y values set as random*multplier
*/
if (method == undefined) {
method = multiplier <= this.pointIntMin ? 'float': 'int'
}
let p = new Point(this[method](multiplier), this[method](multiplier))
return p
}
within(point, max=.5) {
/* Return a random 2D position within the given point.
within({ x: 100, y: 100, radius: 100})
{x: 79, y: 50}
*/
let radius = point.radius * 2
let width = radius
let height = radius
let margin = this.point.radius * 2
let maxMove = width * max
let x = point.x
let y = point.y
// let x = width * .5
// let y = height * .5
let precision = 0
let halfPi = Math.PI / 180
let distance = Math.random() * maxMove
let angle = Math.random() * 360
let tx = x + distance * Math.sin(halfPi * angle)
let ty = y + distance * Math.cos(halfPi * angle)
x = +tx.toFixed(precision)
y = +ty.toFixed(precision)
return [x,y]
}
xy(multiplier=1) {
/*return two random values between 0 and 1 multiplied by the given
value `multiplier`.
This is similar to the random.point() function, except it only returns
an object of {x,y}*/
return {"x":this.float(-multiplier, multiplier), "y": this.float(-multiplier,multiplier)}
}
gaussianFloat(mean=0, stdev=1) {
// Standard Normal variate using Box-Muller transform.
// https://stackoverflow.com/questions/25582882/
// javascript-math-random-normal-distribution-gaussian-bell-curve
const u = 1 - Math.random(); // Converting [0,1) to (0,1]
const v = Math.random();
const z = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
// Transform to the desired mean and standard deviation:
return z * stdev + mean;
}
gaussian(start, end, mean=0, stdev=1) {
return Math.floor(start + this.gaussianFloat(mean, stdev) * (end - start + 1));
}
polar2D() {
let theta = 2 * Math.PI * Math.random();
let R = Math.sqrt(-2 * Math.log(Math.random()));
let x = R * Math.cos(theta);
let y = R * Math.sin(theta);
return [ x, y ];
}
color(h=360, s=100, l=100) {
/* Return a random `hsl` color string,
random.color()
random.color(360, 100, 100)
random.color(360, [30, 100], [60,100])
*/
let ri = random.int.bind(random)
let ia = Array.isArray
let deg = ia(h)? ri(h[0], h[1]): ri(h)
let sat = ia(s)? ri(s[0], s[1]): ri(s)
let lig = ia(l)? ri(l[0], l[1]): ri(l)
return `hsl(${deg}deg ${sat}% ${lig}%)`
}
}
const random = new Random()
Polypoint.head.install('Random')
const randomizePoint = function(px, y) {
/* Perform random() on the X and Y.
If a point is given, randomize to the _max_ of the given point
If a single number is given, assume _square_
If no params are given, discover the stage size.
Use `Point.random()` for the same form, as a new point
let p = new Point()
p.randomize(100, 400)
p.randomize(100) // 100, 100
p.randomize(new Point(100, 400)) // 100, 400
if one of the keys is undefined, no change occurs:
p.setXY(500,700)
p.randomize(100, undefined) // 100, 700
p.randomize(undefined, 400) // 500, 400
p.randomize(undefined, undefined) // 500, 700 // no change occurs.
Note; no params will randomize as much as possible (the stage size)
p.randomize() // 800, 600
Other features would be nice:
+ random in rect (like stage):
p.randomize(rect|dimensions)
+ Randomize other values, e.g radius, colors
p.randomize(['x', 'y', 'radius', 'mass'])
// randomize x to max 400, radius to max 50
p.randomize({ x: 400, radius: 50})
+ In the future, the _origin_; randomize relative to a point:
p.randomize({point, relative: true})
*/
}
copy