互动媒体编程习作——表现随机行为及牛顿运动学

【互动媒体编程习作————使用processing来编写】

使用processing来编写并拓展《代码本色》中的0~4章节程序

(1)第0章 随机游走

主要学习的知识点:

随机游走类;随机数(非均匀分布,均匀分布,自定义分布);Perlin噪声。

实现结果:(PS:第一个有些晃眼)

在这里插入图片描述
这个的实现是在noiseWalk例子的基础上,增加了对R,G,B的随机数取值,以及constrain函数,利用鼠标限制它的运动。
在这里插入图片描述
跟随鼠标指引的随机数Walks,是由紫色画点,并以生成的点为圆心画的圆为开头来游走;在写这个文章的时候突然想到,圆的半径可以利用随机数来形成:就出现了下图线描圈就好看一些了。
在这里插入图片描述
这些都是简单地将可更改的部分代码拼接在了一起,现在来看看示例代码中体现的原理:
第0章——随机游走模型引入了贯穿《代码本色》的两个关键问题:1.如何定义对象的行为规则,2.如何用 Processing模拟这些行为规则。
首先构建随机游走类;类要具有的特征 1】维持自身数据,在屏幕中的位置;2】执行某些动作(进行绘制和移动)。其次,介绍本章中主要的函数:Perlin噪声函数,processing的map函数。
Perlin函数:noise()函数的结果范围是固定的,它总是会返回一个介于 0~1的结果。并且是随着时间推移而发生变化的。例如,一维noise()中:在这里插入图片描述
想让其在代码中变换数值我们就要改变noise()中的参数值,在一维中就是时间t;让t改变后我们得到的数值就会变化。在这里插入图片描述
noise()的值只界定在(0,1)间,不满足变化;map函数来帮忙~map总共五个参数
如下,就将我们得到的数值映射到屏幕大小。

float n = noise(t);
float x = map(n, 0,1, 0,width) ;//用map()函数定制Perl in噪声的范围

在这里插入图片描述
指引画圈程序小结:在这里插入图片描述
蓝色数值的改变,使用高斯随机数生成,只改变了G的数值,还用到constrain函数来限制随机数在0到255之间,
【constrain 函数的作用是限制一个值不超过最大值和最小值,可以用于防止物体越界。constrain(amt被约束值, low最小极限, high最大极限)】

float g = randomGaussian();//设置g值
sd = 20; mean = 200;
g = constrain((g * sd) + mean,0,255);
stroke(123,g,255);//颜色的使用

render()结束,是控制点跟随鼠标运动:

void step() {
    float r = random(1);
    if (r < 0.5) {//自定义概率有50%的几率朝着鼠标前进    
      int xdir = (mouseX-x);
      int ydir = (mouseY-y);
      if (xdir != 0) {
        xdir /= abs(xdir);} 
      if (ydir != 0) {
        ydir /= abs(ydir);}
      x += xdir;
      y += ydir;
    } else {//剩余50%产生-2到2间的随机数
      int xdir = int(random(-2, 2));
      int ydir = int(random(-2, 2));
      x += xdir;
      y += ydir;}
    x = constrain(x, 0, width-1);
    y = constrain(y, 0, height-1);
  }
}

炫彩小球小结:![在这里插入图片描述](https://img-blog.csdnimg.cn/20191218202601841.png
这里用到了下一章节的向量思想,将我们之前定义的x,y用PVector position;来代替。主要代码块:

//Walker类中
noff = new PVector(random(1000),random(1000));//随机生成方向 
position.x=constrain(position.x,mouseX,width);
position.y=constrain(position.y,mouseY,height);//用鼠标限制运动范围
ellipse(position.x, position.y, 48, 48);
void walk() {
    position.x = map(noise(noff.x),0,1,0,width);
    position.y = map(noise(noff.y),0,1,0,height);
    noff.x += 0.01;
    noff.y += 0.01;
  }
//主函数中创立了多个对象;
w = new Walker[20];
  for (int i = 0; i < w.length; i++) {
    w[i] = new Walker(); }//间断生成

另外还有一个新的函数:
noiseDetail()——调整由Perlin噪声功能产生的细节的特征和水平。 类似于物理学中的谐波,噪声是在几个八度计算的。

int o = int(map(mouseX,mouseY,width,1,8));//八音度调节
  noiseDetail(o,0.3);//调整由Perlin噪声功能产生的细节的特征和水平。

全部代码:0随机游走

(2)第一章 向量

主要学习的知识点:
  • 向量的表示,碰撞小球,向量的的运算,加速度。
    这一章主要是掌握利用向量来简化我们的代码,向量可以表示方向。在向量的基础我们可以对其增加力,给予其速度,感受小球的动态效果。程序的实现主要是体现加速度的变化——“朝着鼠标所在方向的加速度”。和随机游走一样,我们确立一个Mover类,用于在主函数中实例化。
class Mover {
  PVector position;
  PVector velocity;
  PVector acceleration;
  float topspeed;}

在这里插入图片描述

void update() {   
    PVector mouse = new PVector(mouseX,mouseY);
    acceleration = PVector.sub(mouse,position);
    acceleration.normalize();
    acceleration.mult(0.2);
    velocity.add(acceleration);
    velocity.limit(topspeed);
    position.add(velocity);}
实现结果:

实现鼠标所指方向给到Movers的加速度,同时通过画线来表示出从屏幕中心点处,到新的运动点位置,形成发散状烟花小球。其中加入了边缘弹回的机制,不让小球流失在外。
在这里插入图片描述
再加些附带值:屏幕四个顶角的牵扯线;不断更新颜色的刷新。
在这里插入图片描述
全部代码:第1章向量

(3)第二章 力

get 学习套路:
●理解力背后的原理。
●将力的公式分解成以下两部分:
如何计算力的方向?
如何计算力的大小?

主要学习的知识点:

牛顿第三运动定律,风力,质量;引力斥力,阻力,摩擦力。
1.力的累加:在忽略质量的前提下,“加速度=力”符合牛顿第二运 动定律。

mover.applyForce(wind);//风力
 mover.applyForce(gravity);//重力

我们不需要在程序中记录加速度,因为它是根据当时的外力计算出来的。在每一帧中对加速度清零,以达到我们在每一次作用时,达到期望变化——最简单的方式,在update()函数的最后将加速度向量乘以0。

void update() { 
velocity.add(acceleration); 
location.add(velocity);
 acceleration.mult(0); }

2.质量:对于实例化的多个物体,设定不同的质量

for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(0.8,6),0,0);//mass=random(0.1,8)质量随机 }

3.重力:加强模拟——根据质量改变重力大小

float m = mover2s[i].mass;
PVector gravity = new PVector(0,0.1*m);//模拟更准确

4.摩擦力:摩擦力的方向和物体运动的方向相反。要先将速度向量单位化,再将单位向量乘以-1。

PVector friction=velocity.get() ;
friction. normalize() ://向量单位化
friction.mult(-1) ;

5.流体阻力
我们需要在Mover类中加入两个额外的函数:isInside()函 数用于判断Mover对象是否在流体对象内部,drag()函数计算并将流体阻力作用 在Mover对象上

实现结果:

根据力的累加、风力,质量,重力知识实现的结果为:
在这里插入图片描述
粉色小球在1/4区域运行;蓝色小球占满整个屏幕;wind风力的施加是利用Perlin噪声生成;并且点击鼠标产生风,释放鼠标后风力消失;会看到按下鼠标时,小球运动加剧。

if (mousePressed) {
       PVector wind = new PVector(0.01,noise(t));
       movers[i].applyForce(wind);
         t+=0.1;  }

全部代码:第2章 力

(4)第三章 振荡

主要学习的知识点:

角度,角运动,极坐标系和笛卡儿坐标系,指向运动的方向,波,三角函数。

1.弧度:用弧度表示一个角,弧度 = 2π × (角度 / 360);利用radian()函数,来转换你想要的角度:float angle = radians(60); rotate(angle);

2.角运动:本章中后续程序的展开都要依靠这个基础,
1>角度 = 角度 + 角速度
2>角速度 = 角速度 + 角加速度
**实现角度运动的加入只需三步:
①把与角运动相关的 变量加入到Mover类中——

class Mover {
float angle = 0;
float avelocity=0;
float aAcceleration=0;

②在update()函数中,用相同的算法同时更新Mover对象的位置和角度——

void update() (
velocity . add(acceleration);//常规的运动
location. add(velocity);
aVelocity +=aAcceleration;
angle +=aVelocity;//新的角运动
acceleration. mult(0); 

③在display()函数中旋转对象——并且要给它一个角加速度!在代码中设置一个初始加速度。float aAcceleration = 0.01;

void display() {
pushMatrix(); //pushMatrix()和popMatrix()使图形的旋转不会影响程序的其他部分 
translate(location.x,location.y); //将原点设为图形所在的位置 
rotate(angle); //转过一定角度 
rect(0,0,mass*16,mass*16); 
popMatrix();}

在我最终实现的程序中,主要运用到的知识有:
1】spaceship控制转向时的“极坐标系和笛卡儿坐标系”

void turn(float a) {
    heading += a;}//获得我们输入的数值
void thrust() {
    float angle = heading - PI/2;
    PVector force = new PVector(cos(angle),sin(angle));……………………

float theta = PI / 4;
float x = r cos(theta); //将极坐标(r,θ)转化为笛卡儿坐标
(x,y) float y = r sin(theta);
2】波:确立角度,角速度,振幅;根据角速度递增角度
例如:
for (int x = 0; x <= width; x += 24) {
float y = map(sin(angle),-1,1,height*4/5,height);
noStroke();
fill(238,233,233,120);
ellipse(x,y,30,30);
angle += angleVel;
}
总结为三步:
1.根据振幅和角度的正弦值计算y坐标; 2.在(x,y)位置画一个圆; 3.根据角速度递增角度。
3】弹力:主要是spring类;确立枢轴点
在这里插入图片描述
4】最后是将上一章的Attractor类改成弹力的写法。
在这里插入图片描述
全部代码为:第3章 振荡

(5)粒子系统

主要学习的知识点:

1.认识粒子系统:
粒子系统就是一系列独立对象的集合,这些对象通常用简单的图形或者点来表示。粒子系统可以用于模拟各种自然现象(比如 爆炸)。典型的粒子系统中都有一个发射器,发射器是粒子的源头,它控制粒子的初始属性, 包括位置、速度等。发射器发射的粒子可能是一股粒子,也可能是连续的粒子流,或 是同时包含这两种发射方式。**关键点:在一个典型的粒子系统中,粒子在发 射器中诞生,但并不会永远存在。**简言之就是“粒子会消亡。”加入生存期(lifespan)变量。

2.使用数组管理这些粒子对象:使用 Java的ArrayList类
ArrayList的使用,结合数组来关联的学习:
数组实现的:
在这里插入图片描述
ArrayList实现的:
在这里插入图片描述
《processing》中可以使用更简洁的方式:
在这里插入图片描述
一个典型的粒子系统会发射连续的 粒子流,因此每个draw()循环都会把新的粒子对象加入ArrayList
利用remove()函数,可以非常方便地移除某个粒子对象(通过对象的下标)。

3.由单个粒子变为粒子系统:
用多态实现粒子系统:
假设没有多态类:
在这里插入图片描述
有了继承和多态就可以进行改进:
在这里插入图片描述
这一点也应该利用于编程实践中,之前有一些就是重复性操作后续可以进行调整。

实现结果:

(彩色喷雾粒子)对单个粒子进行更改做出特别组合。
在这里插入图片描述
全部代码:第4章 粒子系统

总结:

这几次实验探索下来,觉得可以将代码转变成美丽图案,是一件神奇之事。看似复杂,难懂的公式却可以组合出意想不到的图案,在于鼠标,键盘进行交互结合,又是一种奇妙的探索。最后,对于自己的编程实践,仍需要改进,对于这些概念只是了解了皮毛,没有深入探索。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值