实例代码出处:flowfield - OpenProcessing 但是,写的有点啰嗦,我做了精简,加了注释 原理: 每一个流动的粒子,含有一下属性
loc 位置 dir 方向 vel 速率
在实时的计算中,每一帧每一个粒子都进行以下运算 void move() {//perlin噪声的三个参数,分别是xy坐标和当前帧总数(也可以理解为时间)//这样时空之间变建立起转换规则,转换为弧度 float angle=noise(loc.x/500, loc.y/500, frameCount/500);//方向的x,y坐标分别用时空转换来的弧度计算余弦和正弦 dir.x = cos(angle); dir.y = sin(angle);//方向用作速率(其实就是速度了,因为这里有方向) vel = dir.get();//每一个粒子每一帧都乘以speed这个变量放大一下,算是简单的加速度 vel.mult(speed);//位置加上速度进行更新 loc.add(vel);}
欢迎付费咨询 插个广告
做人要酷,这个夏天你要不要学一点C++顺便做点艺术作品?
2017年夏算法艺术实验室Processing基础入门线上课程
修改过后添加注释的代码: //粒子数int num = 1000;//存放粒子的数组Particle[] particles = new Particle[num];void setup() { size(1024, 728); noStroke();//迭代生成所有粒子 for (int i=0; ium; i++) { PVector loc = new PVector(random(width*1.2), random(height)); float angle = random(TWO_PI); PVector dir = new PVector(cos(angle), sin(angle)); float speed = random(.5, 2); particles[i]= new Particle(loc, dir, speed); }}void draw() {//半透明背景 fill(0, 10); noStroke(); rect(0, 0, width, height); fill(255, 155); //遍历数组,每一个粒子都run起来 for (int i=0; ingth; i++) { particles[i].run(); }}//粒子数据类型class Particle {//属性 PVector loc, dir, vel; float speed; color col;//构造函数 Particle(PVector _loc, PVector _dir, float _speed) { loc = _loc; dir = _dir; speed = _speed; }//运动,渲染,越界函数打包在一个函数里 void run() { move(); checkEdges(); render(); }//运动函数 void move() { float angle=noise(loc.x/500, loc.y/500, millis()/10000)*TWO_PI; dir.x = cos(angle); dir.y = sin(angle); vel = dir.get(); vel.mult(speed); loc.add(vel); }//超出窗口就随机一个窗口内位置 void checkEdges() { if (loc.x<0 || loc.x>width || loc.y<0 || loc.y>height) { loc.x = random(width*1.2); loc.y = random(height); } } void render() { ellipse(loc.x, loc.y, 2, 2); }}
|