融入动画技术的交互应用


一、背景

此交互应用《The nature of Code》一书中的技术,基于Processing的Java框架,主要以粒子动画来展现几种自然变化,融入音乐,带来轻松闲适的观感。

二、总体框架


系统框架图

交互系统一共有五个场景,每个场景环环相扣,层层递进,均可进行交互。

在每个场景点击特定位置即可进入下一场景。随着场景的切换,音乐也会产生变化。

由海面大雨到电闪雷鸣再到旭日东升最后到广袤宇宙,总体呈现由暗到明。

三、 动画与交互 

3.1、初始界面


初始界面中,运用了粒子的旋转平移来达到动画效果,交互为随着鼠标移动粒子运动轨迹改变。点击中央的圆即可进入下一场景。

没有任何复杂的原理技术,直接上关键代码:

float i=0.001;

  PVector location;

  PVector velocity = new PVector(-0.1,-0.1,0);

  void update()

  {

    i+=0.005;

    location.add(velocity);

    rotateZ(i);

    rotateY(90);

    rotateX(45);

  }

  void display() {

    pushMatrix();

    translate(location.x*2,location.y,location.z);

    noStroke();

    sphere(10);

    popMatrix();

  }

 void checkEdge()

  {

    if((location.x<-width/3.5) ||(location.x>width/3.5)) {

      velocity.x *= -1;

    }

 if((location.y<-height/3.5)||(location.y>height/3.5)) {

      velocity.y *= -1;

    }

    if((location.z<0) ||(location.z>10)) {

      velocity.z *= -1;

    }}

3.2   Raining Sea

这一场景以粒子系统来模拟暴雨之时波涛汹涌的海面,为了模拟出雨落的效果,给每个粒子y方向上0.1的力使其自由落体。初始化时粒子的位置由随机数控制,使其尽可能自然。同时,每个粒子有不同的加速度,以模拟出错落不一的雨滴,加速度也是随机数控制。

交互方面,点击鼠标会给粒子施加力,力的大小取决于MouseY的大小。点击鼠标可模拟出海面翻涌。同时整体会随着鼠标移动而旋转,这个取决于MouseX。

if ((frameCount % 3) == 0) {

    float x = random(-box, box);

    float z = random(-box, box);

    PVector acc = new PVector(random(-1, 1), random(-1, 1), random(-1, 1));

    for (int i = 0; i < 180; i++) {

      particles.add(new Particlee(new PVector(x+random(2, 12), -box+random(2, 5), z+random(2, 5)), acc));

    } }

……

for (int i = 0; i < particles.size (); i++) {

    Particlee p = (Particlee) particles.get(i);

    p.move();

    p.applyForce(new PVector(0, 0.1, 0));

    float b =abs(sin(radians(p.loc.x+frameCount)))*sin(radians(p.loc.z+frameCount))*cos(radians(p.loc.y))*40;

……

  }

void changeVel(float b) {

    if (loc.y > box-b) hits++;

    if (loc.y > box-b && hits == 1) acc = new PVector(random(-1, 1), random(-1, 1), random(-1, 1));

  }

  void applyForce(PVector force) {

    acc.add(PVector.div(force, 1));

  }

  void boundary(float b) {

    if (loc.x < -box) {

      vel.x *= bounce;

      loc.x = -box;

    }

    if (loc.x > box) {

      vel.x *= bounce;

      loc.x = box;

    }

    if (loc.y < -box) {

     ……

  }

3.3  Rain-Thunder

下雨的模拟与前一场景大同小异在此不多赘述,闪电的实现主要运用了分形。

鼠标每点击一次会出现一次闪电。

Tree(PVector startPoint, PVector direction, float initialWeight) {

  int generation = floor( random(2.0, 5.0) );

    generationMap = new int[generation][];

    generationMap[0] = new int[1];

    generationMap[0][0] = generation ;

 treeSize = generationMap[0][0] + 1;

  int generationSize = generationMap[0][0];

for(int j = 1; j < generation; j++) { 

  if(generationSize == 0) {

        generationMap[j] = new int[1];

        generationMap[j][0] = -1;

        break;

      }

 generationMap[j] = new int[generationSize];

  for(int k = 0; k < generationSize; k++) {

        generationMap[j][k] = floor( random(0.0, 3.0) ); }

generationSize = 0;

for(int k = 0; k < generationMap[j].length; k++) {

 generationSize = generationSize + generationMap[j][k];

      }

treeSize = treeSize + generationSize;

}

branches = new Twig[treeSize];   

 branches[0] = new Twig(startPoint, direction, initialWeight);

int treeIndex = 1;

 PVector currentDirection = direction;

 for(int j = 0; j < generationMap.length; j++) {

 if(generationMap[j][0] == -1) {

    break;  }     

for(int k = 0; k < generationMap[j].length; k++) {       

 int branchNum = generationMap[j][k];

for(int n = 0; n < branchNum; n++){

 int branchIndex = floor(random(0.0, branches[j+k].getPointSum()*0.75));

 branches[treeIndex] = new Twig(branches[j+k].getPoint(branchIndex), currentDirection, branches[j+k].getWeight(branchIndex));

 treeIndex ++;

}  } }  }

3.4  Sun

此处单纯地运用了随机数和向量控制轨迹来绘制,因为颜色没有设置好所以有点午夜蹦迪的感觉。太阳会追随鼠标,鼠标点击住太阳中心即可进入下一场景。

因为太阳的中心位置会随着鼠标移动,所以需要将位置的x、y值设置为全局变量,再在overButton函数中进行判断是否进入下一场景。

这样的图形绘制网上有很多,也没什么技术含量,就不放代码了。

3.5 Galaxy

这里运用的依然是粒子的旋转等,最主要的还是参数的设置。

随着鼠标点击次数增加,会转的越来越快。同时整体会随着鼠标移动而整体旋转。

if (first==0) {

    first = 1;

  } else if (first ==1) {

    xs = new float[n];

    rs = new float[n];

    ss = new float[n];

    zs = new float[n];

    int m = 2;

    for (int i = 0; i

      xs[i] = sq(random(1.4))+random(0.05);

      rs[i] = ((sqrt(sin(random(PI/2))))+(int)random(m)+random(0.01))/m*TWO_PI

        -(9*sqrt(xs[i]));

      ss[i]=  random(1, 4);

      zs[i] = sq((random(0.1)))*(random(1)>.5?-1:1)*xs[i]*10;

    }

    first = 2;

  } else {

    mx+=(mouseX-mx)/4;

    my+=(mouseY-my)/4;

    background(0);

    translate(width/2, height/2);

    fill(255, 150);

    rotate(tilt);

    for (int i = 0; i

      pushMatrix();

      rr = rs[i]-(float)mx/1000;

      float x = xs[i];

      float close = 1+sin(rr-0.5)*sqrt(x);

      translate(0, zs[i]*width);

      scale(1/pow(2, 1-close));

      ellipse(x*width*(cos(rr)+sin(rr)),

        x*width*(sin(rr)-cos(rr))*map(my, 0, height, -0.3, 0.3), ss[i], ss[i]);

      rs[i]+=(x/(x+1)+0*close/4)*speed/xs[i]*(20/frameRate);

      popMatrix();

    }

  }

四、总体展示



基于processing的交互动画系统展示

五、参考资料

《The Nature of Code》 Chapter 0.5、Chapter 1.1、Chapter 2.5、Chapter 4。

openprocessing

你可能感兴趣的:(融入动画技术的交互应用)