使用Javascript,如何生成偏向一端或另一端的随机数?或理想情况下该范围内的一点?
对于上下文:我正在创建一个使用随机灰色方块网格的UI。我正在使用Math.random()
生成灰色的RGB值,但是希望能够将灰色倾斜为平均更暗或更亮,同时仍然具有从黑到白的全范围。
(我认为这是与Skewing java random number generation toward a certain number类似的问题,但我正在使用Javascript ...)
非常感谢任何帮助。
答案 0 :(得分:11)
将Math.random()
提升为获得gamma curve的权力 - 这会改变0到1之间的分布,但0和1保持不变的端点。
var r= Math.pow(Math.random(), 2);
var colour= 'rgb('+r*255+', '+r*255+', '+r*255+')';
对于gamma> 1,您将获得更暗的输出;对于0 <γ<1,你变得更轻。 (这里,'2'给出x平方曲线;平方根曲线的等距亮度为'0.5'。)
答案 1 :(得分:2)
这看起来有点粗糙,不如@ bobince的回答那么优雅,但到底是怎么回事。
//setup
var colours = [], num_colours = 10, skew_to = 255, skew_chance = 20;
//get as many RGB vals as required
for (var i=0; i<num_colours; i++) {
//generate random grey
var this_grey = Math.floor(Math.random() * 256);
//skew it towards the @skew_to endpoint, or leave as-is?
if (Math.floor(Math.random() * 100) >= skew_chance && this_grey != skew_to) {
//skew by random amount (0 - difference between curr val and endpoint)
var skew_amount = Math.floor(Math.random() * Math.abs(this_grey - skew_to));
this_grey += ' (skewed to '+(skew_to < this_grey ? this_grey - skew_amount : this_grey + skew_amount)+')';
}
colours.push(this_grey);
}
console.log(colours);
基本上它会生成随机灰色,然后根据skew_chance
中可能指定的(以百分比形式)决定是否倾斜。 (如果你想偶尔做这个,不是常数)。如果它决定倾斜,则在灰度值中加上或减去一个随机数(取决于偏斜终点是否低于或高于当前值)。
该随机数是介于0和当前值与端点之间的绝对差值之间的数字,例如,如果当前值为40,并且端点为100,则添加的数字将介于0和60之间。
就像我说的那样,@ bobince的答案有点,呃,更优雅!
答案 2 :(得分:1)
[这可能是一个不同的方法。]
此方法涉及以下列方式获取数字:
random = numberToSkewTo + random(-1,1)*stdDeviation
其中:
numberToSkewTo
是您想要偏向的数字。stdDeviation
是与numberToSkewTo
numberToSkewTo + abs(stdDeviation) <= MAX_NUMBER
和numberToSkewTo - abs(stdDeviation) >= MIN_NUMBER
以下代码的作用是,它在给定数字周围选择一个随机数,并且标准偏差不断增加。它返回结果的平均值。
function skew(skewTo,stdDev){
var rand = (Math.random()*2 - 1) + (Math.random()*2 - 1) + (Math.random()*2 - 1);
return skewTo + rand*stdDev;
}
function getRandom(skewTo){
var difference = Math.min(skewTo-MIN_NUMBER, MAX_NUMBER-skewTo);
var steps = 5;
var total = 0.0;
for(var i=1; i<=steps; i++)
total += skew(skewTo, 1.0*i*difference/steps);
return total/steps
}