互动媒体技术——《代码本色》习作四:振荡

1.概念介绍

2.参考案例

3.个人作品

一、概念介绍

  • 简谐运动

1.随时间按余弦(或正弦)规律的振动,或运动。又称简谐振动。
简谐运动是最基本也最简单的机械振动。当某物体进行简谐运动时,物体所受的力跟位移成正比,并且总是指向平衡位置。它是一种由自身系统性质决定的周期性运动。

2.如果质点的位移与时间的关系遵从正弦函数的规律,即它的振动图像(x-t图像)是一条正弦曲线,这样的振动叫做简谐运动。
3.简谐运动有以下两个参数
振幅:离开运动中心的最大距离
周期:完成一次往复运动所花费的时间

  • 带有角速度的振荡
    振荡的公式:
    在这里插入图片描述

二、参考案例

1.案例一:用连续的线条绘制波形
  • 基本原理
    1.利用角速度公式
    在这里插入图片描述
    2.利用振荡的公式简化版
    在这里插入图片描述
    3.说明:
    将坐标屏幕上每隔一定像素绘制点,点的横坐标由自设增量控制,纵坐标由振荡的公式控制,增量通过角速度和角加速度进行控制
  • 代码展示
float angle=0;
float angleVel=0.2;
float amplitude=100;
float startAngle=0;

void setup() {
  size(400, 200);
  background(255);
  smooth();
}
void draw() {
  //background(255);
  if(frameCount%10==0)stroke(random(125, 255), random(125, 255), random(125, 255));  
  strokeWeight(8);
  noFill();
  angle=startAngle;
  beginShape();
  for (int x=0; x<=width; x+=5) {
    float y=map(sin(angle), -1, 1, 0, height);
    //for (int j=0; j<y; j++) {
       // background(255);
      vertex(x, y);
      angle+=angleVel;
    }
 // }
  endShape();
  startAngle+=0.02;
}

  • 效果展示
    在这里插入图片描述
2.案例二:模拟毛毛虫的蠕动
  • 相关介绍
    1.需要准备的数据:角度、角速度、振幅
    2.步骤
    (1)根据振幅和角速度的正弦值计算y坐标
    (2)在(x,y)位置画一个圆
    (3)根据角速度递增角度
    3.核心公式:
    float y=amplitude*sin(angle);
  • 代码展示
//角度
float angle=0;
//角速度
float angleVel=0.2;
//振幅
float amplitude=100;
PImage img;
void setup() {
  size(500, 400);
  frameRate(4);
  img = loadImage("E:\\ProcessingProgram\\love\\work1\\work4_2\\back.jpg");
}

void draw() {
  background(255);
  fill(0, 215, 0 );
  stroke(0);
  image(img, 0, 0);
  for (int x=0; x<=width; x+=25) {
    //根据振幅和角度的正弦值计算y坐标
    float y=amplitude*sin(angle);
    //在(x,y)位置画一个圆
    ellipse(x, y+height/2, 48, 48);
    //根据角速度递增角度
    angle+=angleVel;
  }
}

  • 效果展示

在这里插入图片描述

三、个人作品

作品一:波浪和旋转
  • 基本介绍
    利用带有角速度的振荡实现制作水面浮动的效果以及使用角运动模拟星星的旋转

  • 实现思路
    1.建立两个类,一个为海面的波浪类,另一个为星星类
    2.海面的波浪类:
    (1)利用公式:因为海面波浪的颜色不同层是不同颜色的
    在这里插入图片描述
    (2)同时为了使得每一级波浪之间有差别:即周期长度不一样,在这里可以改变横坐标的增量实现:
    在这里插入图片描述
    (3)通过for循环,改变波浪的颜色和高度和宽度,实现整体波浪起伏的效果
    3.星星类:
    主要通过以方格来模拟星星,使用角运动模拟星星的旋转。在这里构建星星类主要是为了之后的新建对象方便。可以通过构造函数以及成员函数进行参数的改变以及完成绘制工作
    利用公式:
    在这里插入图片描述


  • 在这里插入图片描述

  • 代码展示

//角度
float angle=0;
//角速度
float angleVel=0.2;
//振幅
float amplitude=30;
float record;
//读取图片
PImage img;
//绘制海面的对象
Wave wave;
//星星对象
Star[] star=new Star[100];

//构造函数
void setup() {
  size(600, 400);
  //frameRate(3);
  frameRate(5);
  wave=new Wave(color(65, 105, 225), 150);
  for(int i=0;i<100;i++){
      star[i]=new Star(random(0.1, 8), random(0, width), random(0, 150));
      
  }

}

void draw() {
  background(0);
  //image(img, 0, 0);
  record=0;
  for (int i=0; i<20; i++) {
    record+=random(20, 80);
    print(record);
    float c=100*noise(i);
    wave.reset(color(25+c, 25, 112+c), 150+record,22+random(-10,10));
    wave.drawWave();
  }
  for (int j=0; j<100; j++) {
    //star.reset();
    star[j].aVelocity+=star[j].aAcceleration;
    star[j].oriAngle+=star[j].aVelocity;
    star[j].drawStar();
  }
}
//绘制海面的类
class Wave {
  //海面的颜色
  private color c;
  //海面的高度
  private float level;
  private float add;
  //构造函数
  public Wave() {
    super();
  }
  public Wave(color c, float level) {
    this.c=c;
    this.level=level;
  }
  //改变颜色
  public void reset(color c, float level,float add) {
    this.c=c;
    this.level=level;
    this.add=add;
  }
  //绘制海面
  public void drawWave() {
    fill(this.c);
    beginShape();
    noStroke();
    vertex(0, height);
    for (int x=0; x<=width; x+=add) {
      //根据振幅和角度的正弦值计算y坐标
      float y=amplitude*sin(angle)+this.level;
      //在(x,y)位置画一个圆
      vertex(x, y);
      //根据角速度递增角度
      angle+=angleVel;
    }
    vertex(width, height);
    endShape(CLOSE);
  }
}
//使用角速度模拟星星
class Star {
  //原始角度
  float oriAngle=0;
  //速度
  float aVelocity=1000;
  //加速度
  float aAcceleration=0.001;
  //大小
  float size;
  //位置
  float x;
  float y;

  public Star() {
    super();
  }
  public Star(float size, float x, float y ) {
    this.size=size;
    this.x=x;
    this.y=y;
  }
  //重新设置参数
  public void reset(float size, float x, float y ) {
    this.size=size;
    this.x=x;
    this.y=y;
  }
  //绘制星星
  public void drawStar() {
    fill(255);
    rectMode(CENTER);
    pushMatrix();
    translate(x, y);
    rotate(oriAngle);   
    rect(0, 0, size, size);
    translate(-x, -y);
    popMatrix();
  }
}

  • 效果展示
    在这里插入图片描述
作品二:简单音频可视化
  • 介绍
    利用sound库中的函数获取音频的信息,将音频信息的参数传入到绘图的函数中,可以实现图形的变换和音频的结合。在这个作品中,我设置了音频将会改变绘制图形的y轴位置、半径大小、颜色透明度。当音频声调越高,那么图形绘制的位置将更高,且半径越大,颜色的透明度越小。
    在这里插入图片描述
  • 代码展示
      import processing.sound.*;
      SoundFile soundFile;  //  音频文件
      AudioIn in;  //   音频文件的输入
      Amplitude amp;//  一个音频数据分析器
      float lucency = 0;//  透明度
      float ampvalue = 0; // Amplitude.analyze()的值
      String path = "";// 文件路径
      //创建圆形数组
      Circle[] circle=new Circle[7];
      Circle[] star=new Circle[500];
      float red;
      float green;
      float blue;
      void mouseClicked(){
        red=random(125,255);
        green=random(125,255);
        blue=random(125,255);
      }
      void setup()
      {
        size(800, 400);//设置画布大小
        surface.setResizable(true);//使窗口画布大小可拖动调整
        path = "Refrain.mp3";
        soundFile = new SoundFile(this, path);
        in = new AudioIn(this, 0);
        amp = new Amplitude(this);
        soundFile.play();//播放音频文件
        in.start();
        amp.input(in);
        
        float x=width/7-10;
        float y=height-50;
        //初始化圆形
        for (int i=0;i<7;i++){
          circle[i]=new Circle(50+i*width/7,height-50,50,color(random(125,255),random(0,255),random(0,255)));
        }
        //初始化颜色
        red=125;
        green=125;
        blue=125;
        //初始化星星
        for(int i=0;i<500;i++)
        {
           star[i]=new Circle(random(0,width),random(0,height),2,color(255,255,255));
        }
      } 
      void draw()
      {
        background(0);
        noStroke();
        int m = millis();//获取运行时间(毫秒)
        if (m%10==0)//
        {
           red=random(125,255);
          green=random(125,255);
          blue=random(125,255);
          ampvalue = amp.analyze();//解析音频
          //lastm = m/60;
        }

        for(int i=0;i<500;i++)
        {
          star[i].change(ampvalue);
          star[i].drawCircle();
           
        }
        //标题
        textSize(32);
        fill(255);
        text(path, 30, 40);
        noFill();
      }
      //************定义一个圆形类***************
      class Circle {
        private float centerX;//圆形的中心x坐标
        private float centerY;//圆形中心的y坐标
        private float radius;//圆形的半径
        private color c;//圆的颜色
        private float record;
        //**********构造函数****************
        public Circle(float centerX,float centerY,float radius,color c ) {
          this.centerX=centerX;
          this.centerY=centerY;
          this.radius=radius;
          this.c=c;
          this.record=centerY;
        }
        public void drawCircle(){
          fill(c);
          noStroke();
          circle(centerX,centerY,radius);
        }
        //改变颜色的透明度、圆形的半径和位置
        public void change(float ampvalue){
          this.c=color(red,blue,green, ampvalue*10000+70);
          this.radius=ampvalue*10000/5+25;
          this.centerY=record-100-ampvalue*10000;
        }
      }

  • 效果展示
    在这里插入图片描述
发布了28 篇原创文章 · 获赞 4 · 访问量 5394

猜你喜欢

转载自blog.csdn.net/Program_dancing/article/details/103220573