编程模拟现实世界的力

本文探讨了如何使用编程语言Processing模拟现实中的力,包括牛顿运动定律的应用、风力、重力、摩檫力、流体阻力和引力的模拟。在Processing中,通过计算加速度、力的大小和方向来实现这些力的模拟,如摩檫力的静摩擦力和动摩檫力,流体阻力的计算公式,以及引力和弹力遵循的物理定律。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在用编程模拟自然系统的过程中,很基本的就是对现实世界力的模拟,本篇整理通过代码实现对现实世界力的模拟。

1. 力与牛顿运动定律

在开始模拟力之前,我们先了解力在现实中的概念。从经典的牛顿三大定律开始。

牛顿第一定律

牛顿在《自然哲学的数学原理》中的原始表述是:任何物体都要保持匀速直线运动或静止状态,直到外力迫使它改变运动状态为止。

在Processing中,我们可以将其表述为,在平衡状态下,对象的运动速度(PVector对象)始终是常量。

牛顿第三定律

牛顿第三定律表述:相互作用的两个物体之间的作用力和反作用力总是大小相等,方向相反,作用在同一条直线上。

在Processing中,我们可以将其表述为,如果我们要计算一个由A施加在B上的作用力f(PVector对象),必须额外施加一个由B作用在A上的反作用力(对象PVector.mult(f,-1))。

但是在用Processing编程模拟时,我们不一定要遵循上面的说法。比如说,在模拟风力的效果时,我们就不需要计算物体作用在空气上的反作用力,因为我们根本不会去模拟空气。

牛顿第二定律

牛顿第二运动定律的简单表述为:合力等于质量乘以加速度。

在Processing中,通常我们关注力主要是为了计算加速度,而计算加速度为了获取速度,进而获取对象的位置信息。

此部分内容代码实现:

// 应用力
void applyForce(PVector force) {
    // 加速度 = 力 / 质量
    PVector  a = PVector.div(force, mass);
    acceleration.add(a);
  }

  void update() {
    // 速度 = 速度 + 加速度
    velocity.add(acceleration);
    // 位置 = 位置 + 速度
    position.add(velocity);
    //在每一帧对加速度清零,避免加速度的累加
    acceleration.mult(0);
  }

2. 风力模拟

PVector wind()
{
   // 模拟一个向右的风力
   PVector winds = new PVector(0.01, 0);
   return winds;
}

3. 重力模拟

PVector gravity()
{
   float m = mass;
   // 假设重力加速度为0.1
   PVector gravitys = new PVector(0, m*0.1); 
   return gravitys;
}

4. 摩檫力模拟

摩檫力是一种耗散力。
耗散力:在运动中使系统总能量减少的力。
比如说,开车时,脚踩刹车板会让车通过摩檫力使轮胎减速,它们之间就有摩擦力。
摩檫力分为静摩擦力和动摩檫力。以下只讨论动摩擦力。
在这里插入图片描述
摩檫力的确定分为两个部分:

  • 力的大小
  • 力的方向
PVector friction()
{
  // 摩擦力的大小
  float u = 0.01;
  float N = 1;
  float frictionMag = u * N; // 计算摩擦力的大小(一个随意确定的常量)
  
  // 摩檫力的方向
  PVector frictions = velocity;
  frictions.normalize();
  frictions.mult(-1); // 摩檫力方向与对象运动方向相反
  
  // 摩檫力
  frictions.mult(frictionMag);
  return frictions;
}

5. 流体阻力模拟

流体阻力公式:
F_(d )= -1/2 ρv^2 AC_d v ⃑
processing模拟该力时关注点:
-、 Fd代表阻力,是我们最终要计算的量。

  • -1/2是一个常量,对于模拟该力来说,这个数值大小并没有多少意义,代这个量必须是负数。
  • ρ表示流体密度,是常量,不用关注它。
  • v是对象的运动速度
  • A表示物体前端推动流体流动部分的面积,下述代码中也忽略此量。
  • Cd表示流体阻力,为常数。我们可以根据阻力的强弱确定它的大小。
  • 最后一个参数为力的方向
//判断是否处于流体内
  boolean isInSide() 
{
  // movers为运动对象
  if ((movers.location.x > liquid.x) &&( movers.location.x<liquid.x+liquid.w) && (movers.location.y>liquid.y )&& (movers.location.y<liquid.y+liquid.h)) 
  {//这个条件判断语句可以判断对象的位置是否位于流体的矩形内
    return true;
  } 
  else {
    return false;
  }
}


//浮力
PVector drag()
{
  float c = 0.01;
  float speed = movers.velocity.mag();
  float dragMagnitude = c*speed*speed;
  PVector drags = movers.velocity.get();
  drags.mult(-1);
  drags.normalize();
 if(isInSide()) {
  drags.mult(dragMagnitude);
  }
  else {
  drags.mult(0);
 }
   return drags;
}

6. 引力模拟

在这里插入图片描述
processing模拟该力时关注点:

  • F代表引力,是我们最终计算的量。
  • G是万有引力常量,它的大小不重要。
  • m1和m2代表两个物体的质量。
  • r2表示物体距离的平方。
PVector attract() 
{ 
  float G = 0.4;
  PVector  attractors =  PVector.sub(a.location, b.location);
  // 对象a与对象b的距离
  float distance = attractors.mag();
  // 计算力的方向
  attractors.normalize();
  //符号确定引力或斥力
  float strength = - G * a.mass * b.mass/(distance*distance);
  attractors.mult(strength);

  return attractors;
}

7. 弹力模拟

胡克定律:F = -kx``

/**
* a 枢纽点
* b 
* len 弹簧静止长度
* k 弹力系数
**/
PVector spring(PVector a,PVector b,float len,float k)
{
  PVector springs = PVector.sub(a,b);
  float d = springs.mag();
  float stretch = d - len;
  springs.normalize();
  springs.mult(-1*k*stretch); 
  return springs;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值