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


    序·后羿射日篇

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

      (前情提要:元一直在找寻离开月亮的机会,但无名儿每天缠着元...)

      ...

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

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

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

      “咳咳,我这是在朗诵诗歌呢!”

      ...

    第零章

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

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

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

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

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

    第一节 随机游走

      假设你站在一根独木桥上,每 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 类型)始终都是常量。

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

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

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

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

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

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

      若要计算一个由 施加在 上的作用力 F(Vector 类型),必须额外施加一个由 作用在 上的反作用力 -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

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

      首席工程师:元

      工程阶段:论证中

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

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

      “...”

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

      “...”

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

      “所以?”。

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

    附录

      预知后情,且看下回分解。了解更多请浏览目录导航

  • 相关阅读:
    Jqurey 得到url参数 getUrlParam
    JQUERY获取当前页面的URL信息
    TextView,imageView属性讲解
    滑动解锁
    显示界面跳转,隐式跳转
    代码进行Relativelayout,constraintLayout布局
    代码布局-LinearLayout
    实例xml拖拽详细方法布局
    layout布局
    AS资源了解
  • 原文地址:https://www.cnblogs.com/experdot/p/5448029.html
Copyright © 2020-2023  润新知