現在我們來學如何使用隨機函數,最後幫我們作品的每個 circle 隨機填上不一樣的顏色。
random()
如果我們只接使用無參數版本的 random()
函數,那這個參數會回傳 0 ~ 1
之間的隨機數(但不包含 1),以下執行一個簡單的取隨機數範例:
function setup() {
createCanvas(500, 500);
colorMode(HSB, 500);
translate(width/2, height/2);
textSize(50);
text(random(), -250, 0); // 把隨機數結果寫在畫布上
noLoop(); // 停止 draw() 渲染
}
每次執行都會重新指派一個 0 ~ 1
之間的隨機數。
random(max)
若傳入一個參數,則函數能回傳 0 ~ max
(不包含 max)之間的隨機數。
random(min, max)
若傳入一個參數,則函數能回傳 min ~ max
(不包含 max)之間的隨機數。
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
}
function draw() {
background(100, 10);
translate(width/2, height/2);
var outer_orbit_speed = -frameCount/60/6 * 2 * PI;
var inner_orbit_speed = frameCount/60/3 * 2 * PI;
var inner_orbit_num = 5;
var circle_num = 5;
for (var i = 0; i < inner_orbit_num; i++) {
push();
rotate(outer_orbit_speed);
translate(200 * cos(i / inner_orbit_num * 2 * PI), 200 * sin(i / inner_orbit_num * 2 * PI));
rotate(-outer_orbit_speed);
rotate(inner_orbit_speed);
for (var j = 0; j < circle_num; j++) {
colorMode(HSB, 100);
// stroke(sin(frameCount/60/4)*50+50, 100, 80);
stroke(random(0,100), 100, 80);
circle(100 * cos(j / circle_num * 2 * PI), 100 * sin(j / circle_num * 2 * PI), 20);
colorMode(RGB);
}
pop();
}
}
我們把原本的 stroke(sin(frameCount/60/4)*50+50, 100, 80);
改成 stroke(random(0,100), 100, 80);
,所以從原本的顏色漸變,變成每個 circle 經過每一幀就會隨機變換一個顏色。
但這樣看起來亂糟糟的,如果我們希望的是讓每個 circle 都隨機分配不一樣的顏色,但這顏色經過分配後就不會再隨時間進行改變,我們該怎麼做?
var inner_orbit_num = 5;
var circle_num = 5;
var random_color_list = [];
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
for (var i = 0; i < inner_orbit_num; i++) {
for (var j = 0; j < circle_num; j++) {
random_color_list.push(random(0, 100));
}
}
}
function draw() {
background(100, 10);
translate(width/2, height/2);
var outer_orbit_speed = -frameCount/60/6 * 2 * PI;
var inner_orbit_speed = frameCount/60/3 * 2 * PI;
for (var i = 0; i < inner_orbit_num; i++) {
push();
rotate(outer_orbit_speed);
translate(200 * cos(i / inner_orbit_num * 2 * PI), 200 * sin(i / inner_orbit_num * 2 * PI));
rotate(-outer_orbit_speed);
rotate(inner_orbit_speed);
for (var j = 0; j < circle_num; j++) {
colorMode(HSB, 100);
stroke(random_color_list[i * circle_num + j], 100, 80);
circle(100 * cos(j / circle_num * 2 * PI), 100 * sin(j / circle_num * 2 * PI), 20);
colorMode(RGB);
}
pop();
}
}
我們可以在 setup()
的時候,先用雙重迴圈指派所有顏色到 random_color_list
(一共有 inner_orbit_num * circle_num
個顏色),然後我們再用 random_color_list[i * circle_num + j]
將顏色指派到對應的 circle。
依照我們剛剛完成的作品,每次作品在運行的時候,都會重新隨機指派顏色到每一個 circle,但如果現在我們的需求,是希望每次都能復現原先的隨機分配結果,就需要用到 randomSeed()
函數。
randomSeed(seed)
randomSeed()
接收一個整數參數 seed
,該參數指定一個隨機種子數值,只要該數值固定,往後重新執行 scripit 裡面的 random()
函數都會重現原本的隨機數值:
function setup() {
createCanvas(500, 500);
colorMode(HSB, 500);
translate(width/2, height/2);
randomSeed(100);
textSize(50);
text(random(), -250, -200);
text(random(), -250, -150);
text(random(), -250, -100);
text(random(), -250, -50);
text(random(), -250, 0);
text(random(), -250, 50);
text(random(), -250, 100);
text(random(), -250, 150);
text(random(), -250, 200);
noLoop(); // 停止 draw() 渲染
}
只要指定一個固定的隨機種子,每次執行該 script 都會生成一樣的隨機數列。
var inner_orbit_num = 5;
var circle_num = 5;
var random_color_list = [];
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
randomSeed(20); // 固定一個隨機種子數值
for (var i = 0; i < inner_orbit_num; i++) {
for (var j = 0; j < circle_num; j++) {
random_color_list.push(random(0, 100));
}
}
}
function draw() {
background(100, 10);
translate(width/2, height/2);
var outer_orbit_speed = -frameCount/60/6 * 2 * PI;
var inner_orbit_speed = frameCount/60/3 * 2 * PI;
for (var i = 0; i < inner_orbit_num; i++) {
push();
rotate(outer_orbit_speed);
translate(200 * cos(i / inner_orbit_num * 2 * PI), 200 * sin(i / inner_orbit_num * 2 * PI));
rotate(-outer_orbit_speed);
rotate(inner_orbit_speed);
for (var j = 0; j < circle_num; j++) {
colorMode(HSB, 100);
stroke(random_color_list[i * circle_num + j], 100, 80);
circle(100 * cos(j / circle_num * 2 * PI), 100 * sin(j / circle_num * 2 * PI), 20);
colorMode(RGB);
}
pop();
}
}
只要指定一個隨機種子,我們分配給 circle 的隨機顏色就會是固定的,不會因為重新執行 script 就改變顏色。
如果這些顏色變化看起來太無聊,沒關係!我們把作品的參數調整一下,馬上將這個作品帶向無人之境。
var inner_orbit_num = 80; // 把小公轉軸數量加到 80
var circle_num = 30; // 把每個小公轉軸的 circle 數量加到 30
var random_color_list = [];
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
randomSeed(20); // 固定一個隨機種子數值
for (var i = 0; i < inner_orbit_num; i++) {
for (var j = 0; j < circle_num; j++) {
random_color_list.push(random(0, 100));
}
}
}
function draw() {
background(100, 10);
translate(width/2, height/2);
var outer_orbit_speed = -frameCount/60/6 * 0.5 * PI; // 將大公轉速率調慢 4 倍
var inner_orbit_speed = frameCount/60/3 * 0.5 * PI; // 將小公轉速率調慢 4 倍
for (var i = 0; i < inner_orbit_num; i++) {
push();
rotate(outer_orbit_speed);
translate(200 * cos(i / inner_orbit_num * 2 * PI), 200 * sin(i / inner_orbit_num * 2 * PI));
rotate(-outer_orbit_speed);
rotate(inner_orbit_speed);
for (var j = 0; j < circle_num; j++) {
colorMode(HSB, 100);
stroke(random_color_list[i * circle_num + j], 15, 50); // 調整飽和度跟亮度
circle(100 * cos(j / circle_num * 2 * PI), 100 * sin(j / circle_num * 2 * PI), 5); // 把 circle 直徑調整為 5
colorMode(RGB);
}
pop();
}
}
作品網址:
https://openprocessing.org/sketch/2316255
非常奇妙,調整了一些參數就讓作品變得魔幻起來了,無數個 circle 以一種神秘的秩序互相連動,並且隨機配色的軌跡讓作品隱隱散發各種光芒。
大家也來試試自己調整參數,這些意想不到的變化讓人感嘆 p5.js 的世界真的很美!