欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-27 13:17:19
...

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

第0章 引言
实现了由perlin噪声生成了随时间的变化而产生高速运动,参考了自定义的随机数和perlin噪声亮度

float tx=1;
float ty=1;
float t=1;
void setup() 
{
  size(600,800,P3D);
}
void draw() 
{ 
  loadPixels();
  for (int x = 0; x < width; x++)
  {
      for (int y = 0; y < height; y++)
      {
        t++;
           float bright = map(noise(tx,ty,t),0,1,0,random(0,50));
           pixels[x+y*width] = color(bright);
           ty+=0.01;
      }
     tx+=0.01;
  }
  updatePixels();
}

其中t代表的是时间,亮度则是通过random随机调整的
互动编程习作——表现随机行为及牛顿运动学
第1章 向量

实现了一个颜色随机变换的圆,在区域范围内能够利用WASD四个按钮进行相对应的移动,并且在圆遇到边界的时候会受到一个回弹的速度,参考了弹球程序,向量的速度和加速度。

class Mover 
{  
  PVector location;
  PVector velocity;  
  PVector acceleration;  
  float topspeed;  
  Mover() 
  {    
    location = new PVector(random(200),random(400));    
    velocity = new PVector(2.5,1);    
    topspeed = 5;  
  }   
  void update()
  {    
    if(keyPressed)
    {     
     if(key=='w')
     {        
       acceleration = new PVector(0,-0.001);        
       acceleration.normalize();        
       acceleration.mult(0.2);         
       velocity.add(acceleration);        
       location.add(velocity);      
     }      
     if(key=='s')      
     {        
       acceleration = new PVector(0,0.001);        
       acceleration.normalize();        
       acceleration.mult(0.2);         
       velocity.add(acceleration);        
       location.add(velocity);      
     }      
     if(key=='a')      
     { 
        acceleration = new PVector(-0.001,0);        
        acceleration.normalize();        
        acceleration.mult(0.2);         
        velocity.add(acceleration);              
        location.add(velocity);      
      }      
      if(key=='d')      
      {        
        acceleration = new PVector(0.001,0);        
        acceleration.normalize();        
        acceleration.mult(0.2);         
        velocity.add(acceleration);        
        location.add(velocity);
      }       
      velocity.limit(topspeed);
      if ((location.x > width) || (location.x < 0)) {
      velocity.x *= -10;
}
      if ((location.y > height) || (location.y < 0)) {
      velocity.y *= -10;
}
    }      
}   
void display()
{    
  stroke(0); 
  fill(random(255),random(255),random(255));    
  ellipse(location.x,location.y,50,50);
 
}    
}
Mover mover;
void setup() 
{  
  size(600,800);  
  smooth();
  mover = new Mover(); 
} 
void draw() 
{ 
   background(100,100,100);  
   mover.update();  
   mover.display();  
   
}

Mover类实现了这个程序的各项速度的关系,在小球碰到边界的时候速度这个时候变为反方向的,这也就造成了一种反弹的效果,各个按键按下去的时候,是在原来速度的基础之上再添加一个速度,同时实现了向量的的相加。

互动编程习作——表现随机行为及牛顿运动学
第2章 力和牛顿运动定律
实现了在一个空间内,一组小球做*落体运动,当接触到地面的时候小球静止,键盘上的A和D按键可以给小球添加一个向左或者向右的风力,让小球顺着方向运动,在碰到边界的时候会受到一个弹力,键盘上的W按键可以给小球一个向上的支持力,当松开W键时小球受到重力会下落,参考力的累加,质量的处理,外力的作用,地球引力和物体之间存在极小的引力。

class Mover{
      PVector location;
      PVector velocity;
      PVector acceleration;
      float mass;
      float G=0.04;
      Mover(float m,float x,float y){
      location= new PVector(random(250,750),random(250,750));
      velocity=new PVector(0,-1);
      acceleration=new PVector(0,-1);
      mass=m;
      }
      void applyForce(PVector force){
      PVector f=PVector.div(force,mass);
      acceleration.add(f);
      }
      void update(){
      velocity.add(acceleration);
      location.add(velocity);
      acceleration.mult(0);
      }
      void display(){
         noStroke();
          fill(80,80,80);
          rect(0,750,1000,250);
          fill(80,80,80);
          rect(0,0,1000,250);
          fill(80,80,80);
          rect(750,0,250,1000);
      stroke(0);
      fill(255,0,0);
      ellipse(location.x,location.y,30,30);
      }
      void checkEdge(){
      if(location.x>735){
      location.x=735;
      velocity.x=-1;
      }else if(location.x<15){
      velocity.x=-1;
      location.x=15;
      }
      if(location.y>735){
        location.y=735;
        velocity.y*=0;
      }
    if(location.y<265){
      location.y=265;
      velocity.y*=-1;
    }
}
PVector attract(Mover m){
     PVector force=PVector.sub(location,m.location);
     float distance=force.mag();
     distance = constrain(distance,5.0,25.0);
     force.normalize();
     float strength = -(G*mass*m.mass) / (distance * distance);
     force.mult(strength);
     return force;
     }
}

 Mover[] mover=new Mover[10];
 void setup(){
          size(1000,1000);
          for(int i=0;i<mover.length;i++){
          mover[i]=new Mover(random(0.1,2),random(width),random(height));
          }
       }
       void draw(){
       background(255);
        for (int i=0;i<mover.length;i++){
          for(int j=0;j<mover.length;j++){
            if(i!=j){
          PVector force=mover[j].attract(mover[i]);
          mover[i].applyForce(force);
          }
          }
        float m=mover[i].mass;
        if(key=='A'){
        PVector wind=new PVector(random(-1.5,0),0); 
        mover[i].applyForce(wind);}
        if(key=='D'){
        PVector wind=new PVector(random(0,1.5),0); 
        mover[i].applyForce(wind);}
        if(mousePressed){
        PVector tanli=new PVector(0,-5*m); 
        mover[i].applyForce(tanli);
        }
        PVector gravity=new PVector(0,1*m);
        mover[i].applyForce(gravity);
        mover[i].update();
        mover[i].display();
        mover[i].checkEdge();
      }  
  }

Mover类和第二个实验中的大致相同,在碰到边界的时候小球的速度会变为反方向,同时,在落到地面的时候,小球就变为静止的样子,通过万有引力公式strength = -(Gmassm.mass) / (distance * distance);在小球之间添加了几乎可以忽略的引力
互动编程习作——表现随机行为及牛顿运动学
第3章 震荡
实现了两个圆在背景中间互相绕着做圆周运动,并且将波形代码进行改变,颜色随机转换成了如下图所示的图案,,同时在代码中实现了交互,通过鼠标的点击,可以在屏幕上出现一个一串绳子拉扯着一堆小球进行圆周运动,参考了波,角运动,钟摆以及弹力。

float startAngle = 0;
float angleVel = 0.1;
float r=75;
float theta=0.01;
float aVelocity = 0;
float aAcceleration = 0.001;
float angle1 = 0;
Pendulum p;
void setup() { 
  size(1000,1000); 
  p = new Pendulum(new PVector(width/2,10),125);
  smooth(); 
}
void draw() {
  background(255);
  float angle = startAngle;
  for(float theta=0.1;theta<=PI;theta+=0.5){
  for (int x = 0; x <= width; x +=12) {
    float y = map(cos(angle),-1,1,0,height);
    stroke(0);
    fill(random(0,255),random(0,255),random(0,255));
    ellipse(x+5*sin(theta),y,48,48);
    angle += angleVel;
    //theta+=0.01;
    if(theta>PI){
    theta=0.01;
    }
    }
    }
   p.go();
   fill(175); 
  stroke(0); 
  rectMode(CENTER);
  translate(width/2,height/2); 
  rotate(angle1);
  ellipse(50,0,50,50); 
  ellipse(-50,0,50,50);
  aVelocity += aAcceleration;
  angle1 += aVelocity;
}
class Pendulum { 
  PVector location;
  PVector origin;
  float r;
  float angle;
  float aVelocity;
  float aAcceleration;
  float damping;
  Pendulum(PVector origin_, float r_) { 
    origin = origin_.get(); 
    location = new PVector(); 
    r = r_; 
    angle = PI/4; 
    aVelocity = 0.0; 
    aAcceleration = 0.0;
    damping = 0.05;
  }
  void go() { 
  update(); 
  display(); 
  }
  void update() { 
    float gravity = 0.4; 
    aAcceleration = (-1 * gravity / r)*sin(angle);
    aVelocity += aAcceleration;
    angle += aVelocity;
    aVelocity = damping;
  }
  void display() { 
    location.set(3*r*sin(angle),7*r*cos(angle),3);
    location.add(origin); 
    stroke(0);
    if(mousePressed){
    line(mouseX,mouseY,location.x,location.y+100);
    fill(135,234,100); 
    ellipse(location.x,location.y+100,50,50);
    line(mouseX,mouseY,location.x+50,location.y+100);
     fill(20,23,200); 
    ellipse(location.x+50,location.y+100,50,50);
    line(mouseX,mouseY,location.x-100,location.y-80);
     fill(234,230,200); 
    ellipse(location.x-100,location.y-80,50,50);
    line(mouseX,mouseY,location.x+150,location.y-100);
     fill(60,255,200); 
    ellipse(location.x+150,location.y-100,50,50);
    line(mouseX,mouseY,location.x-250,location.y+100);
     fill(230,23,200); 
    ellipse(location.x-250,location.y+100,50,50);
  }
  }
}

位置 = 位置 + 速度
速度 = 速度 + 加速度
互动编程习作——表现随机行为及牛顿运动学
第4章 粒子系统
实现了在背景中将自定义的图形做成了粒子系统,并且通过鼠标的点击可以将存储的粒子系统生成,参考了ArrayList的使用,单个粒子的生成。

import java.util.Iterator;
ArrayList<Particle>particles; 
ArrayList<ParticleSystem>systems;
Repeller repeller;
ParticleSystem ps;
void setup() { 
  size(1000,1000); 
  particles=new ArrayList<Particle>();
  ps=new ParticleSystem(new PVector(width/2,50));
  systems=new ArrayList<ParticleSystem>();
  repeller = new Repeller(width/2+60,height/2);
  smooth();
}
void mousePressed(){
systems.add(new ParticleSystem(new PVector(mouseX,mouseY)));
}
void draw(){
  background(255);
  particles.add(new Particle(new PVector(width/2,50)));
  Iterator<Particle>it=particles.iterator();
  PVector gravity=new PVector(0,0.5);
  float dx = map(mouseX,0,width,-0.2,0.9);
  PVector wind = new PVector(dx,0);
  ps.applyForce(wind);
  ps.applyForce(gravity);
  for(int i = 0; i < 2; i++) { 
  ps.addParticle();
  }
  while(it.hasNext()){
    Particle p=it.next();
    p.run();
  if(p.isDead()){
  it.remove();
  }
  }
  for(ParticleSystem ps:systems){
  ps.run();
  ps.addParticle();
  }
}
class Particle{
PVector location;
PVector velocity;
PVector acceleration;
float lifespan;
float mass=1;
PShape s;
float angle=0; 
float aVelocity = 0;
float aAcceleration = 0;
Particle(PVector l){
acceleration=new PVector(0,0.05);
velocity=new PVector(random(-1,1),random(-2,0));
location=l.get();
lifespan=255.0;
}
void run(){
update();
display();
}
void update(){
velocity.add(acceleration);
location.add(velocity);
lifespan-=2.0;
}
void display(){
noStroke();
float r=random(0,255);
float g=random(0,255);
float b=random(0,255);
fill(r,g,b,lifespan);
rect(location.x-30,location.y+30,60,20);
ellipse(location.x-30,location.y+40,20,20);
ellipse(location.x+30,location.y+40,20,20);
stroke(0,lifespan);
 pushMatrix();
  rotate(random(0,PI/4));
  s=createShape();
  s.beginShape();
  s.vertex(location.x-10,location.y);
  s.vertex(location.x,location.y);
  s.vertex(location.x,location.y-10);
  s.vertex(location.x+4,location.y-10);
  s.vertex(location.x+4,location.y);
  s.vertex(location.x+14,location.y);
  s.vertex(location.x+14,location.y+4);
  s.vertex(location.x+4,location.y+4);
  s.vertex(location.x+4,location.y+20);
  s.vertex(location.x,location.y+20);
  s.vertex(location.x,location.y+4);
  s.vertex(location.x-10,location.y+4);
   
  s.vertex(location.x+50/2,location.y+18/2);
  s.vertex(location.x+61/2,location.y+37/2);
  s.vertex(location.x+83/2,location.y+43/2);
  s.vertex(location.x+69/2,location.y+60/2);
  s.vertex(location.x+71/2,location.y+82/2);
  s.vertex(location.x+50/2,location.y+73/2);
  s.vertex(location.x+29/2,location.y+82/2);
  s.vertex(location.x+31/2,location.y+60/2);
  s.vertex(location.x+17/2,location.y+43/2);
  s.vertex(location.x+39/2,location.y+37/2);
  s.endShape();
  shape(s);
   popMatrix();
}
void applyForce(PVector force){
    PVector f=force.get();
    f.div(mass);
    acceleration.add(f);
}
boolean isDead(){
if(lifespan<0.0){
return true;
}else{
return false;
}
}
}
class ParticleSystem{
ArrayList<Particle> particles;
PVector origin;
ParticleSystem(PVector location){
  origin=location.get();
particles=new ArrayList<Particle>();
}
void addParticle(){
particles.add(new Particle(origin));
}
void applyForce(PVector f){
 for (Particle p: particles){
p.applyForce(f);
}
}
void applyRepeller(Repeller r){
for (Particle p: particles) {
PVector force = r.repel(p); 
p.applyForce(force);
}
}
void run(){
Iterator<Particle>it=particles.iterator();
while (it.hasNext()){
Particle p=it.next();
p.run();
repeller.display();
if(p.isDead()){
it.remove();
}
}
}
}
class Repeller { 
float strength = 100;
PVector location; 
float r = 10;
Repeller(float x, float y) { 
location = new PVector(x,y);
}
void display() { 
stroke(255); 
fill(255);
ellipse(location.x, location.y, r*2, r*2); 
}
PVector repel(Particle p) { 
PVector dir = PVector.sub(location, p.location);
float d = dir.mag(); 
dir.normalize(); 
d = constrain(d, 5, 100);
float force = -1*strength / (d*d);
dir.mult(force); 
return dir;
} 
}

运用createShape()自己构造了五角星与十字架这两个图案,让他们在一定的角度之内随机扩散。
ArrayList类提供了一个remove()函数,我们可以通过这个函数非常方 便地移除某个粒子对象。
ArrayList的iterator()函数会返回一个迭代器对象。
互动编程习作——表现随机行为及牛顿运动学

相关标签: processing