手繪&碼繪 P2
前言:上一篇文章我們對比了同一幅畫手繪與碼繪的不同,本文著重考慮動態圖的繪製。
PS:考慮到p5與processing區別不大,這裡參考資料都出自p5
背景知識:noise(),返回所定義座標的柏林噪聲值。柏林噪聲是個用來生成比 random() 所能生成更自然及更諧波的隨機數字系列。在 1980 年代有 Ken Perlin 所發明,柏林噪聲至今常被用在圖形應用程式中生成程式紋理、自然運動、形狀、地形等等。
首先我們來看p5.js文件裡所給出的示例:
在p5.js官網給出的示例當中,我們可以看見一組有noise()定義的圖形可跟隨滑鼠有規律生成(gif中滑鼠未能擷取),細看如同自然界中的一輪起起伏伏的山脈。由此為靈感,我們可以適當利用noise()函式完成山脈的繪製。
因而,我們可以先定義一個山脈的函式,Mountain(speed, c, w, h),裡面四個引數分別為速度、顏色、寬度與高度,利用noise()函式生成山巒,並在底部增加一根水平線使其閉合便於填充顏色。
我們先試著生成一組山脈:
暫時看來效果比較搞笑-_-||
沒關係我們生成四組疊加起來看看
這樣看來就比較……(好吧)稍微好一點了!
我們在加個藍天:
現在的效果就比較接近真實的藍天與山脈了
為了使得畫面比較豐富,我們接著生成一組雲彩:
雲彩的生成主要是利用一條水平線與若干半圓組合而成
然後為了白雲動起來更加自然,我們隨機生成了其位置、大小與速度:
好了,最後再加上太陽就大功告成了!
附上(拙劣的)手繪作品:
小結:通過本次實驗,我們完成了“同一幅”作品手繪與碼繪的比較,其感想如下:
技法:手繪注重繪畫功底,側重於藝術性;碼繪注重程式設計能力,側重於對數學與程式碼的完美結合。
工具:傳統的手繪多采用鉛筆、水彩等繪圖工具,隨著電腦技術的不斷髮展,出現了數位板等輔助繪圖工具;而在碼繪中,可以採用的程式設計工具層出不窮,且近年來不斷完善,使得創作者具有更多的選擇。
創作體驗:若是繪製動態影象,手繪的工作量大,需要創作者繪製一幀幀畫面,而碼繪在程式碼中本身嵌入了動態效果,使得這一方面的實現相對輕鬆簡單,作品的互動性也大大提高。
視覺效果:手繪的線條更加自由,創作物件更加天馬行空,全由創作者決定,是創作者自我意識的表達,但這可能也導致與現實的割裂;而碼繪擁有大量嚴謹的函式,其呈現效果更接近的自然的鬼斧神工,觀者看起來也更加舒服。
完整程式碼
var clouds = [];
var x, y, z;
function setup() {
createCanvas(666, 366);
//初始化山脈
a = new Mountain(0.5, '#73b9a2', 90, -30);
b = new Mountain(1, '#367459', 70, 0);
c = new Mountain(2, '#005344', 50, 30);
d = new Mountain(3, '#274d3d', 30, 80);
//初始化白雲
for (var i = 0; i < 14; i++) {
clouds.push(new Cloud(random(1001), random(30, 111), random(0.7, 1.1), random(-2, -0.4)));
}
}
function draw() {
background('#afdfe4');
//顯示山脈
a.display();
b.display();
c.display();
d.display();
//顯示太陽
noStroke();
fill('#ffc20e');
ellipse(100,80,80,80);
//移動白雲
for (var i = 0; i < clouds.length; i++) {
clouds[i].display();
if (clouds[i].x < -60) {
clouds[i].x = 1040;
clouds[i].y = random(10, 100);
clouds[i].size = random(0.7, 1.1);
clouds[i].speed = random(-2, -0.4);
}
}
}
function Mountain(speed, c, w, h) {
this.n = 0.01;
this.inc = speed;
this.w = w;
this.h = h;
this.color = color(c);
this.display = function () {
for (var x = 0; x < width; x++) {
var p = (this.n + x) / this.w;
var nv = noise(p);
var y = ((nv * height) + this.h);
stroke(this.color);
line(x, height, x, y);
}
this.n += this.inc;
}
}
function Cloud(x, y, size, speed) {
this.x = x;
this.y = y;
this.size = size;
this.display = function () {
this.x += speed;
fill('#fffffb');
noStroke();
arc(this.x, y, 25 * size, 18 * size, PI + TWO_PI, TWO_PI);
arc(this.x + 16, y, 22 * size, 45 * size, PI + TWO_PI, TWO_PI);
arc(this.x + 25, y, 22 * size, 35 * size, PI + TWO_PI, TWO_PI);
arc(this.x + 38, y, 32 * size, 20 * size, PI + TWO_PI, TWO_PI);
}
}
參考資料:
[1]:https://www.rand-on.com/projects/2016_dusk_mountains/dusk_mountains.html
[2]:https://blog.csdn.net/magicbrushlv/article/details/77840565