前言:上一篇文章我们对比了同一幅画手绘与码绘的不同,本文着重考虑动态图的绘制。
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