(十二)利用processing模拟现实生活中的力

图形化模拟现实生活中的力

移动的物体类:

//移动的物体
class Mover{
  PVector location;         //物体的位置
  PVector velocity;         //物体的速度
  PVector acceleration; //物体的加速度
  float mass;                 //物体的质量
  float G;                       //万有引力常量,对于常量用大小为 1 表示
  Mover(float m_, float x_, float y_){
    location = new PVector(x_, y_);
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
    mass = m_;
    G = 1;
  }
  Mover(){
    location = new PVector(random(width), random(height));
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
    mass = 1;
    G = 1;
  }
//对物体添加力的作用,改变物体的加速度
  void applyForce(PVector force){
    PVector f = PVector.div(force, mass);
    acceleration.add(f);
  }
//更新速度 v_new = v_old + a(加速度),更新位置,更新加速度为 0 
  void update(){
    velocity.add(acceleration);
    location.add(velocity);
    
    acceleration.mult(0);
  }
  void display(){
    stroke(0);
    fill(175);
    ellipse(location.x, location.y, mass*16, mass*16);
  }
//检测边界窗口边界
  void checkEdges(){
    if(location.x > width){
      location.x = width;
      velocity.x *= -1;
    }else if(location.x < 0){
      location.x = 0;
      velocity.x *= -1;
    }
    
    if(location.y > height){
      location.y = height;
      velocity.y *= -1;
    }else if(location.y < 0){
      location.y = 0;
      velocity.y *= -1;
    }
  }
//检测物体的位置是否处于流体内
  boolean isInside(Liquid l){
    if(location.x > l.x && location.x < l.x+l.w && location.y > l.y && location.y < l.y+l.h){
      return true;
    }else{
      return false;
    }
  }
//对处于流体内的物体添加流体对它的作用,对流体公式简化为 F = c*v*v(流体的具体公式自行查找)
  void drag(Liquid l){
    float speed = velocity.mag();
    float dragMagnitude = 0.5*l.c * speed *speed;
    
    PVector drag = velocity.get();
    drag.mult(-1);
    drag.normalize();
    
    drag.mult(dragMagnitude);
    applyForce(drag);
  }
//计算物体之间的相互斥力,这是应用的万有引力公式,简化的引力公式为 F = (G * m1 * m2)/(distance * distance);  
  PVector disAttract(Mover m){
    PVector force = PVector.sub(location, m.location);
    float distance = force.mag();
    distance = constrain(distance, 5, 10);
    force.mult(-1);
    force.normalize();
    
    float strength = (G * mass * m.mass)/(distance * distance);
    force.mult(strength);
    return force;
  }
//计算物体之间的相互引力
  PVector attract(Mover m){
    PVector force = PVector.sub(location, m.location);
    float distance = force.mag();
    distance = constrain(distance, 5, 10);
    force.normalize();
    
    float strength = (G * mass * mass)/(distance * distance);
    force.mult(strength);
    return force;
  }
}
流体类:

//流体类,
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_;
  }
  void display(){
    noStroke();
    fill(175);
    rect(x, y, w, h);
  }
}
引力类:

class Attractor{
 float mass;
  PVector location;
  float G;
  Attractor(){
    location = new PVector(width/2, height/2);
    mass = 20;
    G = 1;
  }
  Attractor(float m_, float x_, float y_){
    location = new PVector(x_, y_);
    mass = m_;
    G = 1;
  }
  void update(){
    location.x = mouseX;
    location.y = mouseY;
  }
  void display(){
    stroke(0);
    fill(175, 0);
    ellipse(location.x, location.y, mass*2, mass*2);
  }
  PVector attract(Mover m){
    PVector force = PVector.sub(location, m.location);
    float distance = force.mag();
    distance = constrain(distance, 5, 25);
    force.normalize();
    float strength = (G*mass*m.mass)/(distance*distance);
    force.mult(strength);
    return force;
  }
  PVector disAttract(Mover m){
    PVector force = PVector.sub(location, m.location);
    float distance = force.mag();
    distance = constrain(distance, 5, 5);
    force.normalize();
    force.mult(-1);
    float strength = (G*mass*m.mass)/(distance*distance);
    force.mult(strength);
    return force;
  }
}

主函数:

//模拟不同质量物体同时受到风力,重力和摩擦力的运行效果
/*Mover[] mover = new Mover[10];
void setup(){
  size(1200, 200);
  smooth();
  background(255);
  for(int i = 0; i < mover.length; i++){
    mover[i] = new Mover(random(0.1, 5), 0, 0);
  }
}
void draw(){
  stroke(255);
  fill(175);
  //rect(0, height/2, width, height/2);
  PVector wind = new PVector(0.01, 0);
  PVector gravity = new PVector(0, 0.1);
  float c = 0.01;
  float normal = 1;
  float frictionMag = c*normal;
  
  for(int i = 0 ; i < mover.length; i++){
    float m = mover[i].mass;
    PVector gra = PVector.mult(gravity, m);
    PVector friction = mover[i].velocity.get();
    friction.mult(-1);
    friction.normalize();
    friction.mult(frictionMag);
    
    mover[i].applyForce(friction);
    mover[i].applyForce(wind);
    mover[i].applyForce(gra);
    mover[i].update();
    mover[i].display();
    mover[i].checkEdges();
  }
}*/
//模拟不同 质量物体在流体中的运动效果
 /*Liquid liquid;
void setup(){
  size(360, 640);
  smooth();
  for(int i = 0; i < mover.length; i++){
    mover[i] = new Mover(random(0.1, 5), width/2, 0);
  }
  liquid = new Liquid(0, height/2, width, height/2, 0.1); 
}
void draw(){
  background(255);
  liquid.display();
  
  for(int i = 0; i < mover.length; i++){
    if(mover[i].isInside(liquid)){
      mover[i].drag(liquid);
    }
    
    float m = 0.1*mover[i].mass;
    PVector gravity = new PVector(0, m);
    
    mover[i].applyForce(gravity);
    mover[i].update();
    mover[i].display();
    mover[i].checkEdges();
  }
}*/
//模拟不同质量物体在受到引力时的运行效果
 /*Mover[] movers = new Mover[5];
Attractor a;
void setup(){
  size(400, 400);
  for(int i = 0; i < movers.length; i++){
    movers[i] = new Mover(random(1, 2), random(width), random(height));
  }
  a = new Attractor();
}
void draw(){
  //background(255);
  a.display();
 
  for(int i = 0; i < movers.length; i++){
    PVector f = a.attract(movers[i]);
    movers[i].applyForce(f); 
    movers[i].update();
    movers[i].display();
  }
}*/
//模拟不同质量物体在受到引力和斥力的运行效果
Mover[] movers = new Mover[2];
Attractor disA;
void setup(){
  size(600, 600);
  for(int i = 0; i < movers.length; i++){
    movers[i] = new Mover(random(1,1), random(width),  random(height));
  }
  disA = new Attractor(50, width/2, height/2);
}
void draw(){
  //background(255);
  disA.update();
  for(int i = 0; i < movers.length; i++){
    for(int j = 0; j < movers.length; j++){
      if(i != j){
        PVector force = movers[j].disAttract(movers[i]);
        movers[i].applyForce(force);      
      }
    }
    PVector abs = disA.attract(movers[i]);
    movers[i].applyForce(abs);
    movers[i].update();
    movers[i].display();
  }
}


你可能感兴趣的:(processing)