iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Modern Web

p5.js 的環形藝術系列 第 8

[Day 08] p5.js 實戰演練(二) –– 疊合公轉軸(二)

  • 分享至 

  • xImage
  •  

在上一個單元 p5.js 實戰演練(一) –– 疊合公轉軸,我們探討了怎麼在原有的圓周運動再疊加一層公轉軸,並描繪出畫布中四個 circle 的運動軌跡。

Imgur

現在我們想再更進階一些,小公轉軸有 4 個 circle 做圓周運動,我們希望一個大公轉軸也會有四個小公轉軸做圓周運動,也就是說畫布上會出現 16 個 circle,這樣看起來也更加的一般化,每一個公轉軸剛好都繞著四個對象,不管是實際的 circle 或是更小的公轉軸。

不囉唆,先來上個完成結果:

Imgur

這是軌跡版本:

Imgur

現在我們的動畫更加迷人了一些,我們試著從原本的程式改成現在這個動畫的版本,以下是原 code:

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;
	
	// 步驟一:定位小公轉軸的軸心
	rotate(outer_orbit_speed);
	translate(200, 0);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟二:繪製沿著小公轉軸繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
}

照著原本程式的邏輯,我們用一行定義了一個 circle,用了 8 行定義了一個小公轉軸的所有細節,現在有四個小公轉軸,那我們可能需要寫 32 行程式:

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
}

function draw() {
	background(100, 100);
	translate(width/2, height/2);
	
	var outer_orbit_speed = -frameCount/60/6 * 2 * PI;
	var inner_orbit_speed = frameCount/60/3 * 2 * PI;
	
	// 步驟 1-1:定位小公轉軸 1 的軸心
	rotate(outer_orbit_speed);
	translate(200, 0);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 1-2:繪製沿著小公轉軸 1 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	
	// 步驟 2-1:定位小公轉軸 2 的軸心
	rotate(outer_orbit_speed);
	translate(0, 200);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 2-2:繪製沿著小公轉軸 2 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	
	// 步驟 3-1:定位小公轉軸 3 的軸心
	rotate(outer_orbit_speed);
	translate(-200, 0);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 3-2:繪製沿著小公轉軸 3 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	
	// 步驟 4-1:定位小公轉軸 4 的軸心
	rotate(outer_orbit_speed);
	translate(0, -200);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 4-2:繪製沿著小公轉軸 4 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
}

我們分別用 translate(0, 200);translate(200, 0);translate(-200, 0);translate(0, -200); 來定義四個小公轉軸的位置,來看看結果如何:

Imgur

...好欸,整個爛掉,到底是怎麼回事呢?

其實是當我們繪製完每個小公轉軸細節,就要校正回原本的大公轉軸座標系統,因為每個小公轉軸都會 call rotate(inner_orbit_speed);,那看起來必須再 call rotate(-inner_orbit_speed); 校正旋轉,並進行下一個小公轉軸的繪製:

function setup() {
	createCanvas(windowWidth, windowHeight);
	background(100);
}

function draw() {
	background(100, 100);
	translate(width/2, height/2);
	
	var outer_orbit_speed = -frameCount/60/6 * 2 * PI;
	var inner_orbit_speed = frameCount/60/3 * 2 * PI;
	
	// 步驟 1-1:定位小公轉軸 1 的軸心
	rotate(outer_orbit_speed);
	translate(200, 0);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 1-2:繪製沿著小公轉軸 1 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	rotate(-inner_orbit_speed); // 校正回大公轉軸的座標系統
	
	// 步驟 2-1:定位小公轉軸 2 的軸心
	rotate(outer_orbit_speed);
	translate(0, 200);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 2-2:繪製沿著小公轉軸 2 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	rotate(-inner_orbit_speed); // 校正回大公轉軸的座標系統
	
	// 步驟 3-1:定位小公轉軸 3 的軸心
	rotate(outer_orbit_speed);
	translate(-200, 0);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 3-2:繪製沿著小公轉軸 3 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	rotate(-inner_orbit_speed); // 校正回大公轉軸的座標系統
	
	// 步驟 4-1:定位小公轉軸 4 的軸心
	rotate(outer_orbit_speed);
	translate(0, -200);
	rotate(-outer_orbit_speed); // 校正 rotate 函數對座標系統的轉動
	
	// 步驟 4-2:繪製沿著小公轉軸 4 繞行的 4 個 circle
	rotate(inner_orbit_speed);
	circle(100, 0, 20);
	circle(-100, 0, 20);
	circle(0, 100, 20);
	circle(0, -100, 20);
	rotate(-inner_orbit_speed); // 校正回大公轉軸的座標系統
}

Imgur

這是軌跡版本:

Imgur

還是跟我們預期的不太一樣,但好像也蠻好看的 XD

寫 p5.js 有趣的地方就在這裡,有時候 bug 也會生出意料之外的視覺效果,但今天的內容已經夠多了,我們明天再來繼續實驗!


上一篇
[Day 07] p5.js 實戰演練(一) –– 疊合公轉軸(一)
下一篇
[Day 09] p5.js 實戰演練(三) –– 疊合公轉軸(三)
系列文
p5.js 的環形藝術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言