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

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

主题

创作一组编程习作,体现随机行为及牛顿运动学

要求

  • 编程语言与工具:编程工具不限;
  • 作品:参考《代码本色》的第0~4章内容及其实例程序(自行在processing内下载),针对这5章分别编写1个习作(一共5个),每个习作都有不少于2个案例参考,且必须有一定的拓展;
  • 报告:写一篇文章(也可以多篇文章,但最好有一个总的导航文章),发表为博文/推文等形式,描述运用的规律,若用到了数学/物理/化学等学科中的知识,要用平实易懂的语言介绍原理,尝试运用凝练的数学语言表达(公式、方程、推导等),特别要描述出这些原理如何在作品中呈现的。

评价

  • 技术性:技术难度
  • 综合性:通过编程融汇其他学科知识、方法
  • 拓展性:对原作的变化与组合
  • 表现性:艺术表现水平
  • 展示质量:报告+视频+演示程序的直观呈现水平

代码本色

随机游走

float time = 0;
void setup() {
  size(400, 400);
} 
void draw() {
  background(0);
  float x = 0;
   fill(255);
   ellipse(random(width),random(height),1,1);
  while (x < width) {
    stroke(135,206,250);
    line(x, 200 + 50 * noise(x / 100, time), x, height);
    x = x + 1;
  }
  time = time + 0.02;
}

用随机函数random()模拟了夜空中星星闪烁
用柏林噪声函数noise()模拟了海面波浪起伏的效果
在这里插入图片描述

向量

主程序

Mover[] movers = new Mover[20];
void setup(){
  size(600,600);
  
  for (int i = 0;i < movers.length;i++){
    movers[i] = new Mover();
  }
}

void draw(){
  background(255);
  for (int i = 0;i < movers.length;i++){
    movers[i].update();
    movers[i].checkEdges();
    movers[i].display();
  }
  
}

Mover 类

class Mover{
  PVector location;
  PVector velocity;
  PVector acceleration;
  float topspeed;
  
  Mover(){
  
    location = new PVector(random(width), 0);
    velocity = new PVector(1,1);
    acceleration = new PVector(-0.001,0.001);
    topspeed = 5;
    
  }
  
  void update(){
    PVector mouse = new PVector(mouseX, mouseY);
    PVector dir = PVector.sub(mouse, location);
    
    dir.normalize();
    dir.mult(1);
    acceleration = dir;
    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
    if(keyPressed)
    {     
     if(key=='w')
     {        
       acceleration = new PVector(0,-0.001);        
       acceleration.normalize();        
       acceleration.mult(0.4);         
       velocity.add(acceleration);        
       location.add(velocity);      
     }      
      velocity.limit(topspeed);
    }      
  }
  
  void display(){
    stroke(0);
    noFill();
    float w=5;
    stroke(135,206,250);
    strokeWeight(w);
    ellipse(location.x,location.y,32,32);
    stroke(255);
    strokeWeight(1);
    ellipse(location.x,location.y,32-w,32-w);
    ellipse(location.x,location.y,32+w,32+w);
  }
  
  void checkEdges(){
    if (location.x > width) {
      location.x = 0;
    } 
    else if (location.x < 0) {
      location.x = width;
    }

    if (location.y > height) {
      location.y = 0;
    } 
    else if (location.y < 0) {
      location.y = height;
    }
  }
  
}

会跟随鼠标位置进行移动,按W键,会给予圆环一个向上的加速度
在这里插入图片描述

主程序

Mover[] movers = new Mover[20];
Attractor a;
float g = 1;
Liquid liquid;
void setup() {
  size(640,360);
  a = new Attractor();
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(4,12),random(width),random(height)); 
  }
  liquid = new Liquid(0, height/2, width, height/2, 1);
}

void draw() {
  background(255);
  liquid.display();

  a.display();
  a.drag();
  a.rollover(mouseX, mouseY);

  for (int i = 0; i < movers.length; i++) {
    for (int j = 0; j < movers.length; j++) {
      if (i != j) {
        PVector force = movers[j].repel(movers[i]);
        movers[i].applyForce(force);
      }
    }

    PVector force = a.attract(movers[i]);
    movers[i].applyForce(force);
    movers[i].update();
    movers[i].display();
  }
  for (int i = 0; i < movers.length; i++) {
    
    if (liquid.contains(movers[i])) {
      
      PVector dragForce = liquid.drag(movers[i]);
      
      movers[i].applyForce(dragForce);
    }
  }
}

void mousePressed() {
  a.clicked(mouseX, mouseY);
}

void mouseReleased() {
  a.stopDragging();
}

Accractor类

class Attractor {
  float mass;    
  float radius;  
  PVector position;  
  boolean dragging = false; 
  boolean rollover = false; 
  PVector drag;  

  Attractor() {
    position = new PVector(width/2,height/2);
    mass = 10;
    radius = mass * 3;
    drag = new PVector(0.0,0.0);
  }

  PVector attract(Mover m) {
    PVector force = PVector.sub(position,m.position);   
    float d = force.mag();                              
    d = constrain(d,5.0,25.0);                        
    force.normalize();                                  
    float strength = (g * mass * m.mass) / (d * d);      
    force.mult(strength);                                  
    return force;
  }

  void display() {
    ellipseMode(CENTER);
    stroke(0);
    if (dragging) fill (50);
    else if (rollover) fill(100);
    else fill(0);
    ellipse(position.x,position.y,radius*2,radius*2);
  }

  void clicked(int mx, int my) {
    float d = dist(mx,my,position.x,position.y);
    if (d < radius) {
      dragging = true;
      drag.x = position.x-mx;
      drag.y = position.y-my;
    }
  }

  void rollover(int mx, int my) {
    float d = dist(mx,my,position.x,position.y);
    if (d < radius) {
      rollover = true;
    } 
    else {
      rollover = false;
    }
  }

  void stopDragging() {
    dragging = false;
  }

  void drag() {
    if (dragging) {
      position.x = mouseX + drag.x;
      position.y = mouseY + drag.y;
    }
  }
}

Mover类

class Mover {

  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  Mover(float m, float x , float y) {
    mass = m;
    position = new PVector(x,y);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
  }

  void applyForce(PVector force) {
    PVector f = PVector.div(force,mass);
    acceleration.add(f);
  }

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

  void display() {
    stroke(0);
    fill(175,200);
    ellipse(position.x,position.y,mass*2,mass*2);
  }

  PVector repel(Mover m) {
    PVector force = PVector.sub(position,m.position);             
    float distance = force.mag();                                 
    distance = constrain(distance,1.0,10000.0);                             
    force.normalize();                                            

    float strength = (g * mass * m.mass) / (distance * distance);
    force.mult(-1*strength);                                     
    return force;
  }

  void checkEdges() {

    if (position.x > width) {
      position.x = width;
      velocity.x *= -1;
    } 
    else if (position.x < 0) {
      position.x = 0;
      velocity.x *= -1;
    }

    if (position.y > height) {
      position.y = height;
      velocity.y *= -1;
    } 
    else if (position.y < 0) {
      position.y = 0;
      velocity.y *= -1;
    }

  }

}

liquad类

class Liquid {

  
  float x,y,w,h;
  float c;

  Liquid(float x_, float y_, float w_, float h_, float c_) {
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    c = c_;
  }
  
  boolean contains(Mover m) {
    PVector l = m.position;
    if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
      return true;
    }  
    else {
      return false;
    }
  }
  
  PVector drag(Mover m) {
    float speed = m.velocity.mag();
    float dragMagnitude = c * speed * speed;
    PVector dragForce = m.velocity.get();
    dragForce.mult(-1);
    dragForce.normalize();
    dragForce.mult(dragMagnitude);
    return dragForce;
  }
  
  void display() {
    noStroke();
    fill(0, 69, 107);
    rect(x,y,w,h);
  }

}

实现了小球受到黑球的引力以及下半部分水的流体阻力
在这里插入图片描述

震荡

int _frameRate = 60;
int sampling = 100;

float amplitude = 100;
float cycle = 1;
float wavelength = 200;

float offset_time;
float offset_time_velocity = TWO_PI/_frameRate/cycle;

float offset_time_eachPoint;
float point_position_y;

ArrayList<Wave> waves;
Point tempP;
Wave tempW;
void setup() {
  size(400,400);
  frameRate(_frameRate);
  offset_time_eachPoint = TWO_PI / (wavelength/width * sampling);
  waves = new ArrayList<Wave>();
  for (int i = 0; i < 3; i ++) {
    Wave w = new Wave(i);
    waves.add(w);
  }
}

void draw() {
  background(51);
  offset_time += offset_time_velocity;
  
  stroke(255);
  for (int i = waves.size() - 1; i >= 0; i --) {
    tempW = waves.get(i);
    tempW.change();
  }
  

}

class Wave{
  int index_wave;
  ArrayList<Point> points;
  
  Wave(int _i){
    index_wave = _i;
    
    points = new ArrayList<Point>();
    for (int i = 0; i < sampling; i ++) {
      Point p = new Point(i, index_wave);
      points.add(p);
    }
  }
  
  void change() {
    for (int i = points.size() - 1; i >= 0; i--) {
      tempP = points.get(i);
      tempP.move();
      tempP.display();
    }
  }
}


class Point{
  PVector pos;
  int index_point;
  int index_wave;
  float offset_time_currentPoint;

  float shrink;
  float offset_eachWave = PI; 
  
  Point(int _i, int _i_w) {
    index_point = _i;
    index_wave = _i_w;
    pos = new PVector();
    offset_time_currentPoint = index_point * offset_time_eachPoint + index_wave*offset_eachWave;
    pos.x = (index_point+0.5)/sampling*width;
    shrink = pow( sin(pos.x/width * PI), 2);
  }
  
  void move() {
    pos.y = shrink * amplitude * sin(offset_time + offset_time_currentPoint) + height/2;
  }
  
  void display() {
    point(pos.x, pos.y);
  }
  
}

在这里插入图片描述

粒子系统

主程序

ParticleSystem ps;
void setup() {
  size(600, 400);
  ps = new ParticleSystem(new PVector(width/2, 50));
}
void draw() {
 
  background(255);
  ps.addParticle();
  ps.run();
}

Particle类

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
 
  float lifespan;
  Particle(PVector l) {
    acceleration = new PVector(0, 0.05);
    velocity = new PVector(random(-1, 1), random(-2, 0));
    location = l.copy();
    lifespan = 255.0;
  }
  void run() {
    update();
    display();
  }
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan-=1.0;
  }
 
  boolean isDead() {
    if (lifespan <= 0) {
      return true;
    } else {
      return false;
    }
  }
  void display() {
    // border
    stroke(0, lifespan);
    strokeWeight(1);
    fill(random(0,255), random(0,255), random(0,255), lifespan);
    ellipse(location.x, location.y, 3, 3);
  }
}

ParticleSystem类

class ParticleSystem {
  ArrayList<Particle> particles;
  PVector origin;
 
  ParticleSystem(PVector position) {
    origin = position.copy();
    particles = new ArrayList<Particle>();
  }
 
  void addParticle() {
    particles.add(new Particle(origin));
  }
 
  void run() {![在这里插入图片描述](https://img-blog.csdnimg.cn/20200105113233746.gif)
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}

实现了一个烟花效果,随时间慢慢消失
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值