Processing——《下雪的季节》可视化流程
一、前言
灵感来源(也谈不上灵感吧):正值冬季,下雪的季节,做做雪花飘落的“特效 ”也别有一番风味(虽然挺low的,哈哈哈)。更者,正好有一首歌,即名为《下雪的季 节》,所以就又想做些音乐可视化的东西吧,也算锦上添花。
讯享网
二、飘雪的实现
讯享网 有了有趣的想法就开始实现吧,先从比较容易的来写,雪花的绘制。 雪花如果一点点的画那就很难画了,所以这里用了分形的方法画——即递归。 废话不多说直接上代码,代码上有注释
import java.util.Iterator; snowsystem snow; void setup() //建画板 { size(1280,1080); snow =new snowsystem(0.3); //雪花下落频率 } void draw() //重复执行,绘制雪花及其下落过程(动态) { background(40); stroke(240); snow.run(); } class Branch //雪花6个主分叉的其中一个的绘制——分支类 { float radius,ratio,rotation;//类属性,类中全局变量 Branch(float radius_,float ratio_,float rot)//构造函数并赋值{ radius=radius_; ratio=ratio_; rotation=rot; } void generate()//类方法 ——生成完整的一支雪花分枝 { pushMatrix(); rotate(radians(rotation)); //旋转 float len=getStartLength(radius,ratio); branch(len);//递归函数 popMatrix(); } void branch(float len)//主递归函数 { strokeWeight(len*0.15); //线粗细 strokeCap(ROUND); //线端点平滑 line(0,0,0,-len); //画线 translate(0,-len); //移动 if(len>2) //递归终止条件 { pushMatrix(); branch(len*ratio); popMatrix(); pushMatrix(); rotate(radians(-60)); //左 branch(getStartLength(len,ratio)); popMatrix(); pushMatrix(); rotate(radians(60)); //右 branch(getStartLength(len,ratio)); popMatrix(); } } float getStartLength(float length,float ratio)//生成下次开始产生分叉的起点长度 { float len=(1-ratio)*length; return len; } } class snowflake //雪花类 { PVector position ,velocity; float rotation ,aVelocity,radius,ratio; Branch[] branches=new Branch[6]; snowflake(PVector pos,PVector vel,float rot,float aVel,float r,float rat)//构造函数并赋值 { position =pos; velocity=vel; rotation=rot; aVelocity=aVel; radius=r; ratio=rat; for(int i=0;i<6;i++){ branches[i]=new Branch(radius,ratio,i*60);}//生成一个完整的雪花 } void update() { position.add(velocity); //速度 rotation+=aVelocity; //角速度 } void show() { pushMatrix(); translate(position.x,position.y); rotate(radians(rotation)); for(Branch b:branches) {b.generate();} popMatrix(); } } class snowsystem //雪花下落类 { float speed ; ArrayList<snowflake> snowflakes; snowsystem (float speed_){ speed=speed_; snowflakes=new ArrayList<snowflake>(); } void generate() //随机生成新雪花(多个) { PVector position =new PVector(random(0,width),0); PVector velocity =new PVector(0,random(5,10)); float rotation =random(0,360); float aVel=random(-2,5); float radius =random(10,20); float ratio=0.618; snowflake s=new snowflake(position,velocity,rotation,aVel,radius,ratio); snowflakes.add(s); } void emit() //控制雪的大小的函数 (speed一般小于1,否则会比较卡,看电脑配置吧) { if(speed >=1) { for(int i=0;i<speed;i++){ generate();} } else if(speed>0){if(random(1)<speed){generate();}} } void update() //清除落到画布外的雪花 { Iterator<snowflake> ite=snowflakes.iterator(); //迭代器,相当于c++中的队列,按顺序移除进入的雪花 while(ite.hasNext()){snowflake s=ite.next();s.update();s.show(); //在画布中显示下雪的情状 if(s.position.y>(height+s.radius)){ite.remove();} //雪花落到画布外就移除 } } void run () //执行雪花下落 { emit();update();} }

音乐可视化
讯享网 雪花效果出来了 ,下面就是可视化的流程了 processing 提供了两个音频库,一个是sound库;一个是minim库。 这里我用的minim。 ok,直接上代码了就。(部分代码)(比较简单就不写注释了)
import ddf.minim.*; Minim minim; AudioPlayer player; void setup(){ size(1280,626); minim = new Minim(this); player= minim.loadFile("1.mp3"); //打开文件 frameRate(24); } void draw(){ background(0); if(player.left.level()<=player.right.level()){ int r=int(random(255)); int g=int(random(255)); int b=int(random(255)); stroke(r,g,b); } translate(width /9, height / 5); float bins=1024;//最大1024 for(int i=0;i<bins -1;i++) { strokeWeight(2); float r1 = 200 + 150 * player.left.get(i); float r2 = 200 + 150 * player.left.get(i+1); float R1 = 200 + 150 * player.right.get(i); float R2 = 200 + 150 * player.right.get(i+1); float rad1 = 2 * PI * (i / bins); float rad2 = 2 * PI * ((i + 1) / bins); float Rad1 = 2 * PI * (i / bins); float Rad2 = 2 * PI * ((i + 1) / bins); line(r1 * cos(rad1)+500, r1 * sin(rad1)+180, r2 * cos(rad2)+500, r2 * sin(rad2)+180); line(R1 * cos(Rad1)+500, R1 * sin(Rad1)+180, R2 * cos(Rad2)+500, R2 * sin(Rad2)+180); } noFill(); arc(500, 200, 300*player.left.level()*5, 300*player.left.level()*5, -2*PIE, 2*PIE); arc(500, 200, 300*player.right.level()*5, 300*player.right.level()*5, -2*PIE, 2*PIE); translate(-width / 9, -height / 5); if( player.isPlaying() ) { text("Press any to pause playback.", 10, 20); } else { text("Press any key to start playback.", 10, 20 ); } stroke(225); snow.run(); } void keyPressed() //键盘交互 { if( player.isPlaying() ) { player.pause(); } else if ( player.position() == player.length() ) { player.rewind(); player.play(); } else { player.play(); } }


讯享网 这样一个demo就出来了,难免有些单调,后面优化一下。
三、完成了哦!

加了背景,简短的几句代码,就不写了
四、总结
讯享网 只是做了些比较简单粗糙的可视化的内容,但是色彩以及波纹的变换还是会带来一定的 视觉冲击的。同时雪花的飘落配上bgm也是非常有意境的。 而往往更多被用到的手绘,想要达到这种效果简直难到头秃。所以对于做些酷酷的东西 还是果断选择码绘吧。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/71870.html