写在前面

本次实现的交互系统是基于粒子系统的粒子文本效果。本次课程设计主要参考代码本色一书中的内容,系统应用中运用了 《代码本色》 第一章 向量、第二章 、第四章 粒子系统等章节的动画技术,实现的一个文本粒子交互系统。该系统分为白天黑夜两种模式,通过键盘的M 、N键可进行模式的切换,读入本地文本数据,将文本数据用不同类型的粒子实现可视化效果。

接下来进入正题

大家先看看下面这张动图:
它是AE插件实现的文字粒子动画效果,在很多电影电视剧片片头字幕中,都会出现有文字散成飞沙粉尘,这种效果会要用到Particular粒子插件——一款AE粒子插件,它的粒子效果比较酷炫,视觉感官上比较引人注意。

那么,能不能编程来实现一个粒子效果的文字动画特效应用呢

于是就有了本次文字动画特效系统的实现。 此次课程设计的系统基于以上效果,用processing来实现一个效果更丰富,视觉上冲击更强的系统。

要介绍本系统,就不得不介绍一个重要概念——粒子系统 在讲解课程设计过程和最终呈现效果之前,我们先来了解一下 粒子系统 到底是个啥

一、简介

1.1 粒子系统定义

什么是粒子系统?

1982年,卢卡斯影业的研究员William. T. Reeves正致力于电影《星际迷航2:可汗之怒》的制作。整部电影都围绕着创世武器展开,它是一种鱼雷,能让荒芜死寂的星球发生物质重组,最后创造出适合人类居住的环境。电影中有这样一幕,某个星球在被“改造”的过程中,表面蔓延着一道火墙。粒子系统这个术语,就是在这个特效的制造过程中出现的,后来它成为计算机图形学中最常用的技术之一。“粒子系统是由许多粒子组成的用于代表模糊对象的集合。在一段特定时间内,粒子在系统中生成、移动、转化,最后消亡。”

在现在,粒子系统通常表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的游戏图形。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。

这样说可能比较抽象,下面我们通过几张动图来了解和认识它。

① 光束

② 火焰

③ 几何体

通过以上几张动图,我们可以发现,粒子系统一般是由一些基本的元素或者粒子在一定的时间内经过不同的变换而形成的动态效果。通俗的说:粒子系统是一系列独立对象的集合,这些对象通常用简单的图形或者点来表示。

1.2 粒子系统介绍

粒子系统的每个颗粒具有预定的寿命,通常为几秒,在此期间它可以经历各种变化。它在粒子系统生成或发射时开始生命。系统在空间区域内的随机位置发射粒子,形状像球体,半球,圆锥体,盒子或任意网格。显示粒子直到其时间结束,此时它将从系统中移除。系统的排放率虽然确切的发射时间略有随机化,但大致表示每秒发射的粒子数量。排放率和平均颗粒寿命的选择决定了“稳定”状态下的颗粒数量(即,排放和颗粒死亡以相同的速率发生)以及系统达到该状态所需的时间。

发射和寿命设置会影响系统的整体行为,但单个粒子也会随时间而变化。每个都有一个速度向量,确定粒子随每次帧更新移动的方向和距离。速度可以通过系统本身施加的力和重力来改变,或者当粒子被风区吹动时,可以改变速度上的地形。每个粒子的颜色,大小和旋转也可以在其寿命期间或与其当前的移动速度成比例地改变。颜色包括α(透明度)成分,因此可以使粒子逐渐消失,而不是简单地突然出现和消失。

1.3 粒子系统的应用

粒子系统在许多平台上都有广泛的应用,比如unity、Adobe After Effect(AE) 3DMAX、Processing等等,记得去年曾用c语言写过基于OPENGL雨雪的粒子系统,代码结构还是比较复杂的,而在Processing中,由于有自带的粒子系统库,所以粒子系统实现起来相对来说会简单很多。

2 交互系统应用

2.1 整体构思

对于文本粒子交互系统,在AE中有许多插件可以实现,但是在Processing平台应用还不是很广泛,该系统力争实现AE插件中的粒子效果。

基于该交互系统,可延伸扩展为相应的插件或者代码库,便于用户更加方便快捷的实现文本的粒子效果。用户可在该系统上进行扩展,添加额外的功能或者在此基础上加入用户自身的创意和想法。

本次实现的交互系统是基于粒子系统的粒子文本效果。本次课程设计主要参考代码本色一书中的内容,系统应用中运用了《代码本色》第一章 向量、第二章 、第四章 粒子系统等章节的动画技术,实现的一个文本粒子交互系统。该系统分为白天黑夜两种模式,通过键盘的M 、N键可进行模式的切换,读入本地文本数据,将文本数据用不同类型的粒子实现可视化效果。

本系统实现效果 (1)开始界面(鼠标在屏幕上任意点击即可进入交互界面)


黑夜模式(屏幕上有对应按钮,这里录制动图时没有录进去):




白天模式:

2.2 系统框架及代码实现


1、粒子系统类:Particle
先定义基本的粒子属性:粒子位置,速度,加速度等。然后是粒子系统内的函数实现

(1)move函数:用于检查粒子是否足够接近其目标以减慢速度

void move() {// Check if particle is close enough to its target to slow downfloat proximityMult = 1.0;float distance = dist(this.pos.x, this.pos.y, this.target.x, this.target.y);if (distance < this.closeEnoughTarget) {proximityMult = distance/this.closeEnoughTarget;}// Add force towards targetPVector towardsTarget = new PVector(this.target.x, this.target.y);towardsTarget.sub(this.pos);towardsTarget.normalize();towardsTarget.mult(this.maxSpeed*proximityMult);PVector steer = new PVector(towardsTarget.x, towardsTarget.y);steer.sub(this.vel);steer.normalize();steer.mult(this.maxForce);this.acc.add(steer);// Move particlethis.vel.add(this.acc);this.pos.add(this.vel);this.acc.mult(0);}

(2)draw函数:用于粒子的绘制,有多种不同类型的粒子以供用户选择。用户可以通过点击屏幕上的按钮或者点击键盘上对应的字母来更改粒子类型。

void draw(){color currentColor = lerpColor(this.startColor, this.targetColor, this.colorWeight);switch(choice){case 'A': stroke(currentColor);point(this.pos.x, this.pos.y);break;case 'B': noStroke();fill(currentColor);ellipse(this.pos.x, this.pos.y, this.particleSize+10, this.particleSize);ellipse(this.pos.x, this.pos.y, this.particleSize, this.particleSize+10);break;case 'C': noStroke();fill(currentColor);ellipse(this.pos.x, this.pos.y, this.particleSize, this.particleSize);break;case 'D': noStroke();fill(currentColor);triangle(this.pos.x, this.pos.y,this.pos.x+8, this.pos.y,this.pos.x+4, this.pos.y+4);break;default:             // Default executes if the case labelsnoStroke();fill(currentColor);ellipse(this.pos.x, this.pos.y, this.particleSize, this.particleSize);break;}if (this.colorWeight < 1.0) {this.colorWeight = min(this.colorWeight+this.colorBlendRate, 1.0);}}

(3)kill函数:粒子消亡的控制,如果粒子超出指定的场景范围,则将消亡值设置为true,粒子不再显示。

 void kill() {if (! this.isKilled) {// Set its target outside the scenePVector randomPos = generateRandomPos(width/2, height/2, (width+height)/2);this.target.x = randomPos.x;this.target.y = randomPos.y;// Begin blending its color to blackthis.startColor = lerpColor(this.startColor, this.targetColor, this.colorWeight);this.targetColor = color(0);this.colorWeight = 0;this.isKilled = true;}}

2、粒子文字效果实现
(1)generateRandomPos函数:从点的半径中挑选一个随机位置

PVector generateRandomPos(int x, int y, float mag) {PVector randomDir = new PVector(random(0, width), random(0, height));PVector pos = new PVector(x, y);pos.sub(randomDir);pos.normalize();pos.mult(mag);pos.add(x, y);return pos;
}

(2)nextWord函数:使所有粒子绘制下一个单词

void nextWord(String word) {// Draw word in memoryPGraphics pg = createGraphics(width, height);pg.beginDraw();pg.fill(0);pg.textSize(100);pg.textAlign(CENTER);PFont font = createFont(fontName, 100);pg.textFont(font);pg.text(word, width/2, height/2);pg.endDraw();pg.loadPixels();// Next color for all pixels to change tocolor newColor = color(random(0.0, 255.0), random(0.0, 255.0), random(0.0, 255.0));int particleCount = particles.size();int particleIndex = 0;// Collect coordinates as indexes into an array// This is so we can randomly pick them to get a more fluid motionArrayList<Integer> coordsIndexes = new ArrayList<Integer>();for (int i = 0; i < (width*height)-1; i+= pixelSteps) {coordsIndexes.add(i);}for (int i = 0; i < coordsIndexes.size (); i++) {// Pick a random coordinateint randomIndex = (int)random(0, coordsIndexes.size());int coordIndex = coordsIndexes.get(randomIndex);coordsIndexes.remove(randomIndex);// Only continue if the pixel is not blankif (pg.pixels[coordIndex] != 0) {// Convert index to its coordinatesint x = coordIndex % width;int y = coordIndex / width;Particle newParticle;if (particleIndex < particleCount) {// Use a particle that's already on the screen newParticle = particles.get(particleIndex);newParticle.isKilled = false;particleIndex += 1;} else {// Create a new particlenewParticle = new Particle();PVector randomPos = generateRandomPos(width/2, height/2, (width+height)/2);newParticle.pos.x = randomPos.x;newParticle.pos.y = randomPos.y;newParticle.maxSpeed = random(2.0, 5.0);newParticle.maxForce = newParticle.maxSpeed*0.025;newParticle.particleSize = random(3, 6);newParticle.colorBlendRate = random(0.0025, 0.03);particles.add(newParticle);}// Blend it from its current colornewParticle.startColor = lerpColor(newParticle.startColor, newParticle.targetColor, newParticle.colorWeight);newParticle.targetColor = newColor;newParticle.colorWeight = 0;// Assign the particle's new target to seeknewParticle.target.x = x;newParticle.target.y = y;}}// Kill off any left over particlesif (particleIndex < particleCount) {for (int i = particleIndex; i < particleCount; i++) {Particle particle = particles.get(i);particle.kill();}}
}

3、鼠标键盘交互
(1)在屏幕上点击鼠标左键,粒子绘制下一个单词。

void mousePressed() {if (mouseButton == LEFT) {wordIndex += 1;if (wordIndex > words.size()-1) { wordIndex = 0;}nextWord(words.get(wordIndex));}
}

(2)在单词上点击鼠标右键,单词出现爆炸散开的效果

void mouseDragged() {if (mouseButton == RIGHT) {for (Particle particle : particles) {if (dist(particle.pos.x, particle.pos.y, mouseX, mouseY) < 50) {particle.kill();}}}
}

(3)键盘控制不同粒子效果和不同的模式。

void keyPressed() {//nightif ((key == 'M') || (key == 'm')){background(random(50));      bgColor = color(0, 40); }//dayif ((key == 'N') || (key == 'n')){background(random(50,100));bgColor = color(255, 100);}//draw pointif ((key == 'A') || (key == 'a')){choice = 'A';} //draw starif ((key == 'B') || (key == 'b')) {choice = 'B';}//draw circleif ((key == 'C') || (key == 'c')) {choice = 'C';}//draw triangleif ((key == 'D') || (key == 'd')) {choice = 'D';}
}

(4)点击屏幕上的按钮来控制不同形状粒子的绘制。

if(mouseX>=5 && mouseX <=70 && mouseY>10 && mouseY <=32){choice='A';}if(mouseX>=5 && mouseX <=70 && mouseY>32 && mouseY <=77){choice='B';}if(mouseX>=5 && mouseX <=70 && mouseY>77 && mouseY <=122){choice='C';}if(mouseX>=5 && mouseX <=70 && mouseY>122 && mouseY <=167){choice='D';}if(mouseX>=5 && mouseX <=70 && mouseY>167 && mouseY <=212){choice='E';}

4、主函数

void setup() {size(900, 580);background(random(50));      bgColor = color(0, 40);String[] strs = loadStrings("str.txt");for(int i=0;i<strs.length;i++){words.add(strs[i]);}
nextWord(words.get(wordIndex));
}void draw() {// Background & motion blurfill(bgColor);noStroke();rect(0, 0, width*2, height*2);for (int x = particles.size ()-1; x > -1; x--) {// Simulate and draw pixelsParticle particle = particles.get(x);particle.move();particle.draw();// Remove any dead pixels out of boundsif (particle.isKilled) {if (particle.pos.x < 0 || particle.pos.x > width || particle.pos.y < 0 || particle.pos.y > height) {particles.remove(particle);}}}draw_button();if(begin_display){User_Manual();}
}

2.2 系统的讨论

基于该系统,从以下几个方面针对该系统做一些讨论和思索。

(1)系统的创意性

该系统灵感源于AE插件,使用Processing编程平台,基于Java语言,开发一个粒子效果的动画特效系统,用粒子系统来实现文字的可视化。不同的笔画和形状组成一个个的字符,人类将不同的含义赋予这些字符,于是它们便有了属于自己的特殊含义。那么如果将这些字符进一步分解,又会是怎样的视觉效果呢,本系统将一个个文字字符分解开来,看成一颗颗微小的粒子,粒子与粒子之间存在着密切的联系,它们飞舞,跳跃,最终形成我们熟悉的文字效果。鼠标点击,粒子像烟花般绽放然后消散,最终化为虚无,回到本来的样子,世间的万事万物不都是从无到有,最后再化为虚无吗?

(2)系统的功能性

评判一个应用的好坏重要因素之一就是产品的功能和产品的最终价值,该系统功能是较为简洁,可塑性很强。在系统中,运用动画技术,交互技术,将文字动画特效用粒子效果得到很好的呈现,系统分为两种模式可供用户选择,每种模式下,又分为不同的粒子形状效果,给用户视觉效果上的呈现与冲击,带给用户不一样的粒子效果的体验。

(3)系统的应用性

为什么我们要学习粒子系统呢?毫无疑问,粒子系统可以用于模拟各种自然现象(比如爆炸)。实际上,它的作用不局限于此。如果我们要用代码对自然界的各种事物建模,要接触的系统肯定并不是由单个物体组成的,系统内部会有很多物体,而粒子系统非常适合对复数系统进行建模。比如一堆弹球的弹跳运动、鸟群的繁殖,以及生态系统的演化,这些研究对象都是由复数组成的系统。本系统实现的粒子效果文字动画特效可应用在插件扩展
动画片头、动画结尾等地方,将文字用另一种表达方式呈现出来,别具一格。

(4)系统的动画技术性

在大多数游戏中,角色动画是“静止的”。每次角色在屏幕上移动,都是被艺术家创造的一种特制运动。无论它是通过手工精细调制的,还是通过动作捕捉系统来记录的,这种动画都是预定义资源。当一个角色需要执行不同动作时,就需要不同的动画片段。随着计算机技术的发展,程序性动画也在不断地进步,程序性动画是一个角色行为的时间可以程序性的生成。生成程序性的动画最通常的技巧之一就是依赖物理模拟。这个通常取名为基于物理的动画。本系统也是一个程序性动画的简单体现。动画效果在系统呈现上占了很大的比值,不管是粒子汇聚成文字的过程,还是文字四处飞溅,散落成微小粒子的过程。都运用了动画技术。粒子的飞舞半径在程序中可调节,会呈现不同的粒子飞舞效果。

延伸

在做本次课程设计时,不禁对粒子系统有了更深一步的思考,粒子系统就是由一系列独立对象组成的集合。但粒子系统本身不也是一个对象?如果粒子系统也是个对象,我们可以让这些粒子系统对象组成一个集合,产生一个由系统组成的系统。可以尝试着去构建一个由系统组成的系统,再由这个系统组成新的系统,再由新系统组成更高一级的系通统……这样的想法并没有错,毕竟现实世界就是这么运作的,比如:器官是由细胞组成的系统,而人体则是由器官组成的系统,社区是由人组成的系统,城市是由社区组成的系统,依次类推……

我们将粒子系统放在世界中来看,你会发现其实很多事物都是由小小的元素汇聚而成,比如一滴滴水滴汇聚成了河流,一条条河流又汇聚成海洋,一颗颗泥土堆积成小土堆,在量子物理学,有很多地方开始这种讨论,宇宙中的一切都同时具有粒子和波的性质。“一切都是波,没有波动,没有距离。” 宇宙中的一切都有粒子性质。这看起来完全是疯狂的,但这是一个实验性的事实,是通过一个令人惊讶的熟悉的过程得出的。

当然,把真实的物体描述成粒子和波是有些不精确的。准确地说,量子物理学描述的对象既不是粒子也不是波,而是第三类,它们具有一些波的特性和一些粒子的特性。关于在物理导论课程中讨论光作为粒子是否合适在物理教育界引起了一些激烈的争论,不是因为光是否具有粒子性质存在任何争议,而是因为把光子称为“粒子”可能会导致一些学生的误解。我不同意这一点,因为许多把电子称为“粒子”的问题可能会引起同样的担忧。

量子物体的“第三门”性质反映在物理学家用来谈论量子现象的有时令人困惑的语言中。希格斯玻色子是在大型强子对撞机上以粒子的形式被发现的,但你也会听到物理学家们把“希格斯场”说成是一种充满了所有空间的非本地化物质。这是因为在某些情况下更方便讨论希格斯场的作用,而在其他情况下强调了粒子特性,它只是描述同一个数学对象的不同语言。

在宇宙中,我们观察到的所有事物,从物质到辐射,都可以分解为最小的成分。世界上的一切物质都是由原子组成的,原子又是由核子和电子组成的,而核子又分为夸克和胶子。例如,光也由粒子组成,即:光子;引力波。

从根本上说,宇宙究竟是由什么构成的?有没有可能存在最小的基本粒子,或者一组基本粒子,我们既可以用它来建造我们整个宇宙的所有东西,又永远不能被分割成更小的东西?这是一个科学可以解释很多的问题,但它不一定能给我们最终的答案。

附加博文推荐

1、用Processing制作一个「生态瓶」

传送门:https://zhuanlan.zhihu.com/p/64726213
物竞天择,适者生存,不适者被淘汰,挺有趣的生态系统瓶,作者将每一种生物都可以看做是独立的粒子集合,建立单独的粒子类来表示一种生物的行为。将生态系统中的竞争和生存状态用代码展现了出来。

2、Flowing Paint ——感受抽象

传送门:https://blog.csdn.net/qq_40974751/article/details/89483672

作者将抽象的事物具体化,别具一格,该应用的设计以“抽象”一词出发,对热抽象的经典代表作品进行示例展示,通过对画作的颜色提取,并进行交互操作,以及对颜色的重新组合,形成文字,使我们对抽象画本身的理解加深,以及对其颜色组成有了极其深刻的印象。通过不同的交互操作以及音乐的播放,富有一定的趣味性。

3、Magic Network》:一个小孩都能玩的神经网络交互系统

传送门:https://blog.csdn.net/leonardwyh789/article/details/89600881

通过该神经网络可视搭建系统,用户通过该系统可以很直观地了解到神经网络是如何工作的,并且能够十分轻松地搭建出属于自己的简单神经网络。将复杂抽象的神经网络可视化,可以让更多的人了解这个领域。

参考资料:
(1)Openprocessing Creative Coding

(2)The Nature of Code: Simulating Natural Systems with Processing by Daniel Shiffman. 2012 . 周晗彬 译.

(3)粒子系统的应用
https://dev.gameres.com/program/visual/effects/lizi/

(4)AE制作粒子文字特效 Particular粒子插件
https://jingyan.baidu.com/article/5225f26bbdf505e6fb09087c.html

(5) 曹天元. 《 量子物理史话–上帝掷骰子吗》. 2008

融入动画技术的粒子效果文字动画交互应用相关推荐

  1. 怎么在html中加入特效文字,如何使用HTML5+css3实现粒子效果文字动画特效(附完整代码)...

    我们在浏览web网页的时候会发现现在的网页做的越来越美观,很多动画特效做的越来越炫酷,这离不开HTML5和css3的深入开发.今天我们要来分享一款基于HTML5和css3的文字特效--粒子效果文字动画 ...

  2. html怎么把字做成动画效果,如何使用HTML5 css3实现粒子效果文字动画特效(附完整代码)...

    摘要 腾兴网为您分享:如何使用HTML5 css3实现粒子效果文字动画特效(附完整代码),学宝,小米社区,手机管家,神州专车等软件知识,以及小学英语点读机,便利宝,startos,工资宝,玩,大将军手 ...

  3. ae制h5文字动画_如何使用HTML5+css3实现粒子效果文字动画特效(附完整代码)

    我们在浏览web网页的时候会发现现在的网页做的越来越美观,很多动画特效做的越来越炫酷,这离不开HTML5和css3的深入开发.今天我们要来分享一款基于HTML5和css3的文字特效--粒子效果文字动画 ...

  4. 超好看的粒子效果文字动画特效HTML5源码

    介绍: 一款基于HTML5 Canvas的文字特效原作者(Shape Shifter),输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的文字动画,相当酷的动画效果.喜欢的可以下载 ...

  5. h5酷炫粒子java代码_html5粒子效果文字特效

    特效描述:html5 粒子效果 文字特效.html5粒子效果文字特效 代码结构 1. HTML代码 BLUR = false; PULSATION = true; PULSATION_PERIOD = ...

  6. 小学计算机教案动画欣赏,小学信息技术《文字动画》教案

    一.教学目标 1.能说出制作文字动画的步骤,并能利用Ulead GIF Animator制作文字动画. 2.通过合作探究完成首尾帧及自动渐变效果的制作,提高合作交流及动手操作能力. 3.通过制作宣传标 ...

  7. 动画学习记录: SVG文字动画

    b站看到的一个比较有意思的svg动画代码,记录一下 svg可以通过即时设计生成 效果 具体代码 <!DOCTYPE html> <html lang="en"&g ...

  8. android 粒子动画火焰,canvas粒子火焰跟随动画特效

    使用方法: 1.head引入css文件 html { overflow: hidden; user-select: none; background-color: black; } html body ...

  9. html5字体动画效果,7款超华丽的HTML5 Canvas文字动画特效

    原标题:7款超华丽的HTML5 Canvas文字动画特效 文字是网页中最为常见的元素之一,当然我们使用最多的就是调整文字的颜色.大小等基本属性.有时候我们在一些活动页面上需要展示特别样式的文字效果,这 ...

最新文章

  1. SAP PM技术对象的功能
  2. python学习费用-深圳python学习费用多少
  3. Laravel 文件夹结构简介
  4. linux gpio设备驱动程序,嵌入式Linux设备驱动开发之:GPIO驱动程序实例-嵌入式系统-与非网...
  5. android 9 pie公司,Android 9.0正式推送 定名Android Pie
  6. PowerShell监控——监控共享打印机 获取打印记录、打印人员、打印文件等详细信息
  7. listview选中高亮
  8. W,b的初始化和几种激活函数
  9. VB6 如何添加自定义函数 模块 把代码放到一个模块中
  10. mysql一张表能存多少条数据不影响性能_MySQL|优化案例两则
  11. 北理乐学c语言,北京理工大学2018年计算机考研889数据结构考试大纲
  12. 天下谁人不识“金” — SONY NW-WM1ZM2 索尼金砖二代测评
  13. 使用yocs_smoother_velocity做速度平滑处理
  14. 取消 android 内部收费,国产手机硬伤终于被揭开:若安卓系统下半年收费,该如何应对?...
  15. java关注列表_如何从一个Instagram帐户中获取关注者列表?
  16. ppt矩形里面的图片怎么放大缩小_如何使用PPT调节图片的大小
  17. algoc++之求解根号2
  18. Windows Server之浅谈SMB以及SMB小案例分享
  19. Java播放MP3播放音频
  20. 微信开发者模式php,微信开发之开发者模式

热门文章

  1. java多态猫狗吃骨头_javaSE学习(6):面向对象:多态的两个经典案例(猫狗案例和南北方人案例)...
  2. CPU、内存、磁盘的性能瓶颈及理解
  3. laravel excel 2.1
  4. 前端基础学习笔记 背景 渐变 倒影 遮罩
  5. 跳动的爱心代码--李峋爱心代码(完整源码)
  6. android7.1 打印机 (ghostscript+hpijs - hplip)
  7. 人为何会生病?(1)
  8. webp转换gif动图的方法-批量转换并保留动画效果
  9. 如何利用电脑榨干闲置的带宽资源?
  10. 海思HI3751_Android解决方案 开发指南