您的位置:首页 > 编程语言

编程模拟自然(七):力学矢量与牛顿定律

2016-04-30 03:20 309 查看

  旧书有云:古者十日并出,草木焦槁,一曰后羿者射日,太阳里之九鸟皆死,救苍生于涂炭。

  传闻后羿所用箭矢加持了力学模拟系统,可实现深空精确制导,才得以击落太阳。

  ...

  “星星挂在天边,就像梦想遥不可现...”元哼唧着。

  “猿叔你在哼什么曲子啊?”

  “...星星消失在天边,就像诺言来不及实现...”元对无名儿捂着双耳选择无视。

  “咳咳,我这是在朗诵诗人小刚的诗歌呢!”

  ...

第零章

  “星星挂在天...你爸曾经射落过太阳?”元刚要继续深情朗诵,似乎想到了什么。

  “是的,听娘说爹地最厉害了。”

  “我不信,那你说他是怎么办到的?”元不禁抬头望了望天际那颗水蓝色星球。

  “用的是力学系统...”

  “猿叔,你手中的粒子系统就内嵌着呢!”无名儿继续回答道

第一节 随机游走类

  假设你站在一根独木桥上,每10秒钟抛一枚硬币:如果硬币正面朝上,你向前走一步;背面朝上,则向后退一步。这就是随机游走——由一系列随机步骤构成的运动轨迹。然后,从独木桥转移到地面,你就可以做二维的随机游走了,不过每走一步需要抛掷两次硬币,而且需要按如下规则

第一次抛掷第二次抛掷结果
正面正面向前走一步
反面正面向右走一步
正面反面向左走一步
反面反面向后走一步
  这是一个很简单的规则,但是随机游走可以对现实世界中的各种现象建模:从气体分子的运动到小孩一整天的玩耍活动不一而足。

  现在我们建立Walker对象,它表示一个可以随机游走的对象,具有以下特点:即维持了自身数据(位置),又能够执行某些动作(比如绘制自身或者移动一步)

  首先,我们定义一个Walker类——Walker对象的模板

''' <summary>
''' 表示一个随机游走对象
''' </summary>
Public Class Walker
Public X As Integer
Public Y As Integer
End Class


  构造函数负责对象的初始化

''' <summary>
''' 初始化当前对象的位置
''' </summary>
''' <param name="initX">指定的对象位置X分量</param>
''' <param name="initY">指定的对象位置Y分量</param>
Public Sub New(initX As Single, initY As Single)
Me.X = initX
Me.Y = initY
End Sub


  新建一个Move()方法实现控制对象移动

''' <summary>
''' 当前对象随机移动一帧
''' </summary>
Public Sub RndMove()
Dim chioce As Integer = Rnd.Next(4) '随机值0、1、2或3
If chioce = 0 Then
X = X + 1
ElseIf chioce = 1 Then
X = X - 1
ElseIf chioce = 2 Then
Y = Y + 1
Else
Y = Y - 1
End If
End Sub


  新建一个Walker实例,并在一个过程里循环调用它的RndMove()方法,每次调用完毕就输出到屏幕,我们就可以看到它的随机运动轨迹



第二节 向量

  这里指的是欧几里得向量,即几何向量。它的定义是:一个既有大小又有方向的几何对象。在编程中,引入向量并不会给我们添加新工作,它会简化你的代码,而对于在运动模拟中经常出现的数学运算,向量提供了很多现成的函数。

  现在,将上述Walker类中的变量用向量等效替换。

Imports System.Numerics
''' <summary>
''' 表示一个随机游走对象
''' </summary>
Public Class Walker
Public Location As Vector2
Public Shared Rnd As New Random
''' <summary>
''' 初始化当前对象的位置
''' </summary>
''' <param name="initX">指定的对象位置X分量</param>
''' <param name="initY">指定的对象位置Y分量</param>
Public Sub New(initX As Single, initY As Single)
Location = New Vector2(initX, initY)
End Sub
''' <summary>
''' 当前对象随机移动一帧
''' </summary>
Public Sub RndMove()
Dim chioce As Integer = Rnd.Next(4) '随机值0、1、2或3
If chioce = 0 Then
Location = Location + New Vector2(1, 0)
ElseIf chioce = 1 Then
Location = Location + New Vector2(-1, 0)
ElseIf chioce = 2 Then
Location = Location + New Vector2(0, 1)
Else
Location = Location + New Vector2(0, -1)
End If
End Sub
End Class


  新增加速度和速度属性,并添加方法NormalMove(),

Public Velocity As Vector2
Public Acceleration As Vector2
''' <summary>
'''  当前对象物理仿真移动一帧
''' </summary>
Public Sub NormalMove()
Velocity = Velocity + Acceleration '更新速度
Location = Location + Velocity '更新位置
End Sub


  容易知道三个向量间的作用关系是一种“涓滴”效应,加速度影响速度,进而影响位置。



  新建多个Walker实例,并在一个过程里循环调用它的NormalMove()方法,并记录下轨迹。



第三节 力与牛顿定律

  我们首先要了解力在现实世界中的概念,力可以指代力量的强度,比如“她用力的推动那块大石头”,或者“他有力地说出那句话”。但是这里是更书面化的概念,它源自牛顿运动定律:


  力是一个向量,它使有质量的物体产生加速。


  当看到定义的第一部分——力是一个向量,你应该由衷的感到喜悦,同位置或加速度一样,这在编程中可轻松被描述。

  结合力的概念,我们需要看看牛顿三大运动定律。

  牛顿第一运动定律通常简要的描述为:


  物体有保持静止或运动的趋势。


  这个表述遗漏了外力的作用,可以扩展为:


  除非有不均衡外力的作用,负责物体保持静止或匀速直线运动状态。


  而在编程中,我们可以这样表述牛顿第一定律:


  在平衡状态下,对象的速度向量(Vector类型)始终都是常量。


  然后先跳过牛顿第二定律,直接牛顿第三定律,它通常表述为:


  每个作用力都有一个大小相等、方向相反的反作用力


  这个表述容易引起误解,可以更好的表述为:


  力总是成对出现的,且这两个力大小相等,方向相反


  同样地,这个表述也会引起误解,因为它看起来像是说:成对出现的力总是会互相抵消,事实并非如此,成对出现的力不是作用在同一物体上的。

  从编程角度表述牛顿第三定律:


  若要计算一个由A施加在B上的作用力F(Vector类型),必须额外施加一个由B作用在A上的反作用力-F


  有时候不一定要遵循上述说法,比如模拟风力效果时,就不需要计算物体作用在空气上的反作用力,因为根本不用去模拟空气。

  下面是牛顿第二定律,它被表述为:


  合力等于质量乘以加速度:F=M*A


  现在我们用编程去模拟这条定律,结合力的累加原理和牛顿第二定律,新增ApplyForce()方法

Public Property Mass As Single = 10.0 '质量大小
''' <summary>
''' 指定的力作用于当前对象
''' </summary>
''' <param name="fVec">指定的力</param>
Public Sub ApplyForce(fVec As Vector2)
Acceleration = Acceleration + fVec / Mass
End Sub


  更新NormalMove()方法,需要将加速度清零

''' <summary>
'''  当前对象物理仿真移动一帧
''' </summary>
Public Sub NormalMove()
Velocity = Velocity + Acceleration '更新速度
Location = Location + Velocity '更新位置
Acceleration = New Vector2(0, 0) '加速度清零
End Sub


  现在,你可以创建任意的或者使用符合现实物理规律的一个力,并将它作用于Walker对象。

后记

  “猿叔,你在做什么?”

  “起草一份文书...”

  “我问过我娘了,她不愿多说爹地的事情。”无名儿说话时有些失落。

  “哈哈,就说是你编的嘛,射日的事我是不会相信的!”

  “你最厉害,行了吧。”

  “那是当然,我可是创世神,谁能比我厉害。”元一副不可一世的样子。

  “哟,还创世神,你咋不上天咧?”

  “....”

  “你怎么知道我要上天?”元晃了晃手中的文稿。


  中文名称:后羿工程

  英文名称:Hou Yi Project

  别称:星际载人火箭登地工程

  首席工程师:元

  工程阶段:论证中

  工程目标:实现可载人登地


  “唉,现在月球上好多偏远地方的孩子还上不起学;”无名儿努力皱了皱眉。

  “...”

  “吴刚叔每天辛苦砍树却没人给他发工资;”接着叹了口气。

  “...”

  “登地这种事又有什么意义呢?”

  “所以?”元瞧了眼无名儿稚嫩的脸庞。

  “你不要走呗,不然没人陪我玩了。”

附录

1.预知前情,请看上回分解。也可以浏览目录导航

2.资源推荐:https://github.com/shiffman/The-Nature-of-Code-Examples

3.参考书籍:《The Nature of Code》[美] Daniel Shiffman 著
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: