“至爱梵高·星空之谜” :noise 算法尝试

Loving Vincent Van Gogh

去年被这个片子刷屏,朋友圈的文艺仔们纷纷转发评论,为了不俗套,我选择用写程序的方式表达对‘神’的仰慕。

这个标题起的有点纠结,因为梵高和noise没啥关系。只是梵高的笔触,尤其是这副著名的《星空》总我让联想到perlin noise 算法的特性(perlin noise 维基百科)

学建筑的朋友知道,photoshop中的添加云彩滤镜用的就是noise算法,再比如在渲染玻璃的时候,为了更加真实我们通常会给玻璃的反射加一点噪波(noise)等等。除此之外,noise算法可以生成很多漂亮的图像,这个网站上有些介绍:(转到博客)

不同frequency下的noise图像

基于noise的vector field

我生成的图像如下:参考了一些案例(openprocessing),因为noise算法本身的代码结构形式固定,所以只需要设计代码的框架和几个重要参数。

                                                                                        生成图像截图

p5.js 代码如下:

var particles_a = [];
var particles_b = [];
var particles_c = [];
var nums =300;
var noiseScale = 900;

function setup(){
	createCanvas(windowWidth, windowHeight);
	background(21, 8, 50);
	for(var i = 0; i < nums; i++){
		particles_a[i] = new Particle(random(0, width),random(0,height));
		particles_b[i] = new Particle(random(0, width),random(0,height));
		particles_c[i] = new Particle(random(0, width),random(0,height));
	}
}

function draw(){
	noStroke();
	smooth();
		for(var i = 0; i < nums; i++){
		var radius = map(i,0,nums,1,2);
		var alpha = map(i,0,nums,0,250);
		fill(69,33,124,alpha);
		particles_a[i].move();
		particles_a[i].display(radius);
		particles_a[i].checkEdge();
		fill(7,153,242,alpha);
		particles_b[i].move();
		particles_b[i].display(radius);
		particles_b[i].checkEdge();
		fill(255,255,255,alpha);
		particles_c[i].move();
		particles_c[i].display(radius);
		particles_c[i].checkEdge();
	}  
}

function Particle(x, y){
	this.dir = createVector(0, 0);
	this.vel = createVector(0, 0);
	this.pos = createVector(x, y);
	this.speed = 0.4;
	this.move = function(){
		var angle = noise(this.pos.x/noiseScale, this.pos.y/noiseScale)*TWO_PI*noiseScale;
		this.dir.x = cos(angle);
		this.dir.y = sin(angle);
		this.vel = this.dir.copy();
		this.vel.mult(this.speed);
		this.pos.add(this.vel);
	}
	this.checkEdge = function(){
		if(this.pos.x > width || this.pos.x < 0 || this.pos.y > height || this.pos.y < 0){
			this.pos.x = random(50, width);
			this.pos.y = random(50, height);
		}
	}
	this.display = function(r){
		ellipse(this.pos.x, this.pos.y, r, r);
	}
}

未完待续:后续会更新noise的其它小应用和教程……

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注