24
2021
06

二维世界中质量密度体积关系的问题

问题描述

之前我们提到过,二维力学实验仿真中存在一个问题:二维力学引擎中,质量 = 密度 * 面积。而真实世界中,质量 = 密度 * 体积。虽然二维世界的物理规律也是完备的,但是学生学习过程中还是以3维世界为准的。

问题分析

二维世界中:m = ρ * S

三维世界中:m = ρ * V

用户是无法直接看到数据的,只能通过实验来测得这些物理量。(真实世界也是一样的,我们也是先给出定义,然后再通过实验测得物理量。)

以小球为例,我们看一下,用户可以通过哪些方式测得质量、密度、体积。

体积

  1. 质量/密度。

  2. 用直尺测量小球直径,然后根据公式计算小球体积。

  3. 小球全部浸没在水中,测量排开液体的体积。

密度

  1. 根据材质,查表。

  2. 质量/体积。

  3. 排水法,转化成水的密度。

质量

  1. 密度*体积。

  2. 根据胡克定律来测量(包括弹簧测力计,弹簧振子等)。

  3. 使用天平、电子天平、杠杆尺等测量。

  4. 通过碰撞试验、匀加速试验等测量。

我们测物体的质量,其实是转化成测物体的重力,物理引擎中,力是以冲量的方式来表示的。

我们要保证物体的质量是正确的,这样就能保证大多数情况下物理引擎算出的结果是正确的。

用户用直尺测量,然后计算体积,我们是无法造假的。

物体的材质给定了,物体的密度也就确定了,我们也不能造假。但是,密度用户是看不到的,所以我们只要保证用户通过实验测量得到的密度和查表得到的密度一致就可以了。

上面的分析中,我们得到:

  1. 保证质量是正确的。

  2. 通过直尺测量,然后计算体积,是正确的。

问题解决

方法1

保证密度是正确的,修正体积的测量结果。

正常来说,保证质量正确的前提下,是无法保证密度也正确的。但是物理引擎(nape和box2d)允许用户自己设置质量,也就是说物理引擎中,可以有m ≠ ρ * S。

这样一来,我们同时保证了密度和质量都是正确的,接下来,只需要想办法让用户测得的体积是正确的。

通过测量直径,计算体积,我们已经保证了。我们还需要解决一个问题,就是小球排开液体的体积。

物理引擎中并没有真正实现排开液体,排开液体需要我们自己实现,需要根据物体和液体的相交面积来计算。还需要考虑浮力,也是通过相交面积来计算。所以,我们要解决的问题是,修正物体和液体的相交面积。

具体实现: 我们在nape的FluidProperties中,添加了一个volumeScale属性,然后再ZPP_FluidArbiter的preStep方法中,计算质量的时候,乘上volumeScale。

box2d修改起来更简单一些,可以自己尝试。

方法2

不使用用户自定义质量,保证密度是正确的,修正体积的测量结果。

和上面的思路一样,只是不使用用户自定义质量。这样就还需要修正质量计算。

对于nape来说,这种方法不现实,需要修改的地方太多,不好找,容易出错。

但是对于box2d或者其它物理引擎,这种方式可行。box2d中,只需要修改Shape子类的ComputeMass方法。改动很少,没有太大的风险。

方法3

不使用用户自定义质量,不保证密度是正确的,修正体积的测量结果。

和方法2的不同之处在于,不保证密度是正确的,保证 ρ = m / S 成立。

我们不用去修正质量的计算,但是依然要修正浮力的计算,而且浮力计算的时候,除了要修正相交面积,还要修正液体的密度。也就是说除了体积修正参数外,还需要给液体设置两个密度,一个用于计算质量,一个用于计算浮力。

nape中默认支持这个功能,只需要分别设置FluidProperties中的density和Material中的density即可。box2d中需要自己添加一个参数。

总结

之前觉得这个问题无解,除非使用3D模型来计算。但是实际开发中,最终解决方案也不是特别复杂。

当然,这种方式也不是完全没有问题,比如液体受到液体浮力的情况,比如小球非完全浸没的情况。

有没有其它没想到的问题,还有待验证。


« 上一篇下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。