美文网首页
交互动画——Processing实现灯的转换与3D地球展示

交互动画——Processing实现灯的转换与3D地球展示

作者: PoetSailor | 来源:发表于2019-04-29 23:10 被阅读0次

一、课程简介

参考《代码本色》教程,运用不少于3个章节的动画技术,实现一个交互应用,将动画技术充分运用于交互过程中;最好能充分融入其他课程的知识。

二、学习过程

在基于Processing的Java环境下,我重新整理了类的对象的关系,在这里我找了两个非常有代表性的代码作品,并在上面自己又加以修改并进行理解:

1、Processing实现灯的转换

首先,我们需要将灯的变换写入一个函数框架中进行调用,画面中将实现九个LED灯,我们的目标是将鼠标交互和LED灯颜色与形状变换结合起来。

LED灯采用HSB颜色模型,在HSB模式中,H(hues)表示色相,S(saturation)表示饱和度,B(brightness)表示亮度。

色相(H,hue):在0~360°的标准色轮上,色相是按位置度量的。在通常的使用中,色相是由颜色名称标识的,比如红、绿或橙色。黑色和白色无色相。

饱和度(S,saturation):表示色彩的纯度,为0时为灰色。白、黑和其他灰色色彩都没有饱和度的。在最大饱和度时,每一色相具有最纯的色光。取值范围0~100%。

亮度(B,brightness或V,value):是色彩的明亮度。为0时即为黑色。最大亮度是色彩最鲜明的状态。取值范围0~100%。

HSB模式中S和B呈现的数值越高,饱和度明度越高,页面色彩强烈艳丽,对视觉刺激是迅速的,醒目的效果。

转换:colorMode(mode) //mode:GRB或者HSB

          colorMode(mode, max) //常用范围为0.0~1.0,以max设置所有颜色组成

          colorMode(mode, max1, max2, max3)//RGB,255,255,255;HSB,360,100,100;

          colorMode(mode, max1, max2, max3, maxA) //maxA指透明度的最大值   (见链接3)

在draw函数中需要用到循环函数进行绘画重复,使用:for(int i=0;i < ledlist.size(); i++)   

在动画方面,我们设置了①鼠标点击旋转圆圈并转换成矩形进行运动;②鼠标再次点击的同时颜色也要不停改变;③鼠标最后点击时回归圆形形状,颜色在改变的最后那个色停止。

这一节的难点在于循环体的编写,所以在代码部分借鉴了很多源代码的部分。

2、3D地球展示

Processing可以画出三维图像比如Box,Sphere等,这里列举了将矩阵推送到矩阵堆栈的函数 pushMatrix();

交互在于鼠标和球体维数的变化。

三、代码内容

1.ArrayList ledlist;

int ledwidth =100;

boolean ispressed = false;

void setup()

{

size(500, 500);

ledlist = new ArrayList();

LED led1 = new LED(width/2-ledwidth-100, height/2-ledwidth-100, ledwidth);

LED led2 = new LED(width/2-ledwidth-100, height/2, ledwidth);

LED led3 = new LED(width/2-ledwidth-100, height/2+ledwidth+100, ledwidth);

LED led4 = new LED(width/2, height/2-ledwidth-100, ledwidth);

LED led5 = new LED(width/2, height/2, ledwidth);

LED led6 = new LED(width/2, height/2+ledwidth+100, ledwidth);

LED led7 = new LED(width/2+ledwidth+100, height/2-ledwidth-100, ledwidth);

LED led8 = new LED(width/2+ledwidth+100, height/2, ledwidth);

LED led9 = new LED(width/2+ledwidth+100, height/2+ledwidth+100, ledwidth);

ledlist.add(led1);

ledlist.add(led2);

ledlist.add(led3);

ledlist.add(led4);

ledlist.add(led5);

ledlist.add(led6);

ledlist.add(led7);

ledlist.add(led8);

ledlist.add(led9);

}

void draw()

{

background(0);

for(int i=0;i < ledlist.size(); i++)        //遍历绘画函数

{

LED led = ledlist.get(i);

led.draw();

}

}

void mousePressed()

{

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

{

LED led = ledlist.get(i);

led.update();                              //当鼠标点击时更新状态

}

}

class LED {

int x;//X轴向位置

int y;//Y轴线位置

int state;//状态量

int k;//开关变量

int w;//大小

int degs;//角度

int c;//颜色

LED(int x_, int y_, int w_) {    //构造函数初始化变量

x = x_;

y = y_;

w = w_;

c = (int)random(0,360);        //初始化随机赋颜色

state = 0;

k = 0;

degs = 0;

}

void update()                    //检测鼠标是否悬停在方框内

{

if (overRect(x-w/2, y-w/2, w, w))

{

state ++;                    //鼠标点击,三种状态循环切换

if (state >= 3)

{

state = 0;

}

}

}

void draw()

{

colorMode(HSB,360,100,100);    //使用HSB颜色模型

if (state == 0)                //第一种情况,呈现原有状态

{

pushMatrix();

translate(x, y);

rotate(radians(degs));

fill(c,100,100);

noStroke();

rectMode(CENTER);

ecllipse(0, 0, w, w);

popMatrix();

} else if (state == 1)          //第二种情况,旋转圆->矩形

{

pushMatrix();

translate(x, y);

rotate(radians(++degs));

fill(c,100,100);

noStroke();

rectMode(CENTER);

rect(0, 0, w, w);

popMatrix();

} else if (state == 2)            //第三种情况,改变颜色

{

pushMatrix();

translate(x, y);

rotate(radians(degs));

if (k == 0)

c ++;

if (k == 1)

c --;

if (c <=0)

{

c = 0;

k = 0;

}

if (c >= 360)

{

c = 360;

k = 1;

}

fill(c,100,100);

noStroke();

rectMode(CENTER);

rect(0, 0, w, w);

popMatrix();

}

}

boolean overRect(int x, int y, int width, int height) {

if (mouseX >= x && mouseX <= x+width &&

mouseY >= y && mouseY <= y+height) {

return true;

} else {

return false;

}

}

}

2.

void setup() {

  // 全屏

  fullScreen(P3D);

  // 文字大小

  textSize(32);

}

float timer = 0;

void draw() {

  //背景

  background(0);

  // 绿色边框

  stroke(#74F599);

  //不设置填充

  noFill();

  // 环境光

  lights();

  //将当前变换矩阵推送到矩阵堆栈

  pushMatrix();

  translate(width/2, height/2, 200 * sin(timer));

  // 鼠标左键拖动旋转

  if (mouseButton == LEFT) {

    rotateX(mouseY * 0.05);

    rotateY(mouseX * 0.05);

    // 通过调整球体网格的顶点数量来控制用于渲染球体的细节。默认分辨率为30

    sphereDetail(mouseX / 4);

  }

  // y 轴旋转

  rotateY(timer);

  // x 轴旋转30

  rotateX(PI/6);

  //球密度

  sphere(300);

  // 球体中部文字

  textMode(CENTER);

  fill(255, 0, 0);

  text("Hello world,My name is liShengFu!", -300, 0, 0);

  popMatrix();

  timer = (timer+0.01)%TWO_PI;

  text(year() + "年"  + month()+ "月" + day()+ "日" +hour()+ "时" +

    minute()+ "分" +second()+ "秒", 50, height-50, 0);

}

void mouseClicked() { 

  // 鼠标右键保存图片

  if (mouseButton == RIGHT) {         

    String picName = "PDE_" + year()+ "_" + month()+"_" + day()+"_" + 

      hour()+"_" + minute()+"_" + second(); 

    save(picName + ".png"); 

    println(" ----> Picture saved.");

  }

}

四、效果图

动图链接:https://www.jianshu.com/p/9e7e61b15db5

五、参考资料

链接1 https://blog.csdn.net/fddxsyf123/article/details/62848357

链接2 https://blog.csdn.net/qq_39097425/article/details/84946559

链接3 https://blog.csdn.net/Hewes/article/details/76383246

相关文章

网友评论

      本文标题:交互动画——Processing实现灯的转换与3D地球展示

      本文链接:https://www.haomeiwen.com/subject/nycpnqtx.html