在过去的几周中,我们介绍了P5.js并将其用于生成带纹理的纸张背景和相对压倒性(但很有趣!) 的watercolor表示 。 在这篇文章中,我们将讨论可重复的随机性以及为什么要使用它(提示:可重复性!)。 然后,我们将深入研究并更新代码,以利用可重复的随机性来帮助我们隔离和保留所生成的最佳视觉效果。
到目前为止,使用我们已经编写的代码,每次浏览器评估我们JavaScript时,水彩图像都会发生变化,有时会发生巨大变化。 这是设计使然。 我们使用计算机生成的随机性作为工具来创建各种视觉效果,并进一步促进我们的艺术创作。 但是,从视觉的角度来看,这些结果并不都令人满意,并且某些结果可能使我们比其他人更接近我们想象的艺术。
让我们刷新浏览器,观察可能永远不会再产生的随机性组合,直到我们生成非常吸引人的图像为止。 关于水彩斑点的位置和颜色有些感觉不错,但也许我们想使这些斑点更小,更不透明。 但是,如果我们更改定义斑点大小或不透明度大小范围的常数的值,则必须刷新页面-这样就失去了完美的位置和大小组合。
理想情况下,我们可以浏览随机结果,并在看到自己真正喜欢的东西时冻结所有这些随机值。 然后,我们可以修改图像的其他元素,以查看在冻结的随机值集合下它们的结果。 我们将使用种子随机数生成器来完成此操作。
带种子的随机数生成器将获取“种子”(这只是某种随机字符串,数字等),并返回从该种子生成的数字序列。 给定相同的种子,随机数生成器将返回相同的数字序列。 不同的种子,不同的数字。 通过使用种子,我们得到了可重现的随机结果。 我们获得了可重复的随机性。
通过迫使我们自己生成一个种子并传递到随机数生成器中,我们还承担了一些负担。 不过,权衡是值得的,因为现在我们可以在处理其他变量的同时冻结所有随机值。 我们可以保存我们喜欢的图像的种子,并在任何时间点重新创建它们。
不幸的是,JavaScript的Math.random()
不支持种子,因此我们将依赖于一个流行的名为seedrandom的库,该库提供了可种子的随机数生成器。 我们将使用的seedrandom API的子集非常简单(上面的示例使用了该API)。
本质上,我们将使用seedrandom()
函数创建一个随机数生成器函数,该函数将在需要新的随机数时调用。 为了简化流程,我创建了一个立即执行的匿名函数,该函数可以选择获取随机种子的值。 如果没有传递种子,我们将生成12个随机数,将它们连接起来,并将其用作种子。 使用的每个种子都将注销到控制台,因此,如果您喜欢所看到的内容,只需从控制台复制种子并将其传递到函数中即可。
const STARTER_SEED = undefined;
const random = ((seed) => {
if (seed) {
console.log(`Using user-defined seed: ${seed}`);
return seedrandom(seed);
}
let seeds = [];
let rnd = seedrandom();
for(let i = 0; i < 12; i++) {
seeds.push(rnd());
}
console.log(`Using seed: ${seeds.join('')}`);
return seedrandom(seeds.join(''));
})(STARTER_SEED);
// call random() to get a random number
找到所需的种子后,只需将其设置为STARTER_SEED
的值STARTER_SEED
。 然后,对random()
调用将以相同的顺序返回相同的数字。 这意味着您可以修改代码中不会更改对random()
的调用次数或顺序的任何部分,并且仍然希望在结果图像中看到许多相同的元素。 以下是我找到自己喜欢的种子,然后使用同一种子调整某些随机范围的过程:
如您所见,可重复的随机性为我们提供了计算机提供的随机性的好处,而又没有放弃对该过程的完全艺术控制。 与往常一样, 此处的代码可在GitHub上获得 。 您有什么想法,问题或喜欢的种子吗? 在评论中或Twitter 上将它们发布在这里: @freethejazz 。