图形化模拟现实生活中的力
移动的物体类:
//移动的物体
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();
}
}