为什么物理引擎PhysicsJS中的重力加速度为0.0004?

11

或者更好的说,这是什么意思?

这些单位应该是什么?

如果我正在尝试模拟对“背景”产生的摩擦力,就像这样:

return this
    .velocityDirection
    .mult(mu * this.mass * g)
    .negate();

我希望使用 g 作为 9.80665 m/s^2。在使用 PhysicsJS 之前,它一直是这样工作的:

var
    frictionForce;
    frictionForce = vec2.create();
    vec2.scale(
        frictionForce,
        vec2.negate(
            frictionForce,
            this.velocityDirection
        ),
        mu * this.mass * g
    );
return frictionForce;

我曾经使用glMatrix进行线性代数计算。

我一直将质量用千克,力用牛顿等单位表示,但在PhysicsJS中似乎不是这样的。(例如:如果有一个半径为1的圆形物体,它的半径是多少?因为当我必须将这个值用于其他地方时,以及"转换"为屏幕上的像素时会产生差异)

现在我正在使用物理库,感觉好像缺少了一些物理知识...

我希望有人能指导我更好地理解它。我正在查看API文档,学到了很多,但没有找到我想要的答案。

更新

我得到了一个非常直接的答案。这只是想让任何感兴趣的人知道我接下来做了什么...

由于Jasper和dandelany的帮助,我更好地理解了PhysicsJS的一些工作原理。为了实现我的愿望,在PhysicsJS中使用牛顿、每秒米等输入(并且还有可配置的像素每米比率),我决定创建另一个求解器。

它只是原始(默认)verlet integrator的略微变体。我在这篇(粗略的)文章Metres, Seconds and Newtons in PhysicsJS中对它进行了解释。


可能只是一个“可行”的值。在游戏中,将像素视为现实世界单位是棘手的。想象一下,“1像素=1英尺”——为了在合理的时间内下落一定距离,这个重力常数必须是多少像素/秒²?最好的方法就是尝试不同的值,直到看起来正确为止 :-) - Jongware
@Jongware 哇...我真的不想相信。 =P 以前我自己处理移动,并“使用”通常的单位(至少相对于彼此)。我只是设置1米等于50像素,一切都很好。但随时可以手动调整这种关系。然后我可以用真实的值模拟真实的力。就像 Burak Kanber 所做的一样。(http://burakkanber.com/blog/modeling-physics-javascript-gravity-and-drag/) ... 我还没放弃。=) - slacktracer
3个回答

6
单位为像素和毫秒。
因此,加速度为0.0004像素/毫秒²。
使用米作为单位并不合理,原因有很多。每英寸的像素数取决于设备。即使进行了转换,加速度为9.8 m/s²也会看起来非常快,因为通常计算机模拟想要从远处观看物体...因此,您不希望屏幕上的一个米对应模拟中的一个真实米。

1
加速度与观察被加速物体的距离有什么关系? - Bergi
当然,我不希望屏幕上的一米在模拟中也是一米。我只想选择一米应该有多少像素。如果我能考虑到通常的单位(牛顿、米、秒、每秒米等),我的模拟将会像“真实世界”一样。我只需要选择:一米有多少像素(这将考虑到我所看的“距离”。比如说,从“这里”看一个180厘米的人高50个像素(例如),其他所有东西都会相应地调整... 我是否真的忽略了什么明显的使它不合适或不可行的事情? - slacktracer
如果你想进行这些转换,但它高度依赖于屏幕分辨率,而且看起来也很奇怪。它会看起来像你把物体直接放在了屏幕上方。它们会极快地掉下去。通常大多数应用程序希望创建一个场景,就好像你是从远处观察它一样。不是直接在你眼前。这是一个视角的问题。 - Jasper
我真的不明白,@Jasper。对我来说,这个转换就是视角问题。首先,我说这个一米高的盒子将有50个像素,然后我的相机,我的视角缩小了,现在它只有10个像素。对于我的模拟来说,这并不重要。如果盒子每秒向右移动两米,它将继续以每秒两米的速度向右移动,现在意味着每秒向右20个像素(好吧,我在想一个正方形)。无论如何,我现在有了答案。还有新的问题。如果你有任何关于进行转换的提示,我非常感慨。非常感谢。 - slacktracer
抱歉再次强调。我想要被理解。=P 最后的话。保证。 如何将所有内容转换为像素是一个渲染问题,而不是物理问题... 再次非常感谢。再见。 - slacktracer
显示剩余2条评论

5
显然,我还不能在帖子上发表评论,所以这是对Jasper答案的跟进,因为你要求提供转换技巧:Jasper给出的单位是0.0004 px/ms/ms(或px/ms^2)。知道了单位,使用单位消除法就可以很容易地进行转换。首先,我们将该数字转换为px/s^2: 0.0004 px/ms^2 * 1000 ms/s * 1000 ms/s = 400 px/s^2 由于我们知道地球上的重力约为9.8 m/s^2,这意味着默认值模拟的比例为: 400 px/s^2 * (1/9.8) s^2/m ~= 41 px/m 因此,使用默认设置时,PhysicsJS正在模拟一个一米长的世界,它等于41个像素。如果我们使用您的示例,“一个180厘米高的人有50个像素高”,那么我们将转换为以下比例: 50px / 0.180m ~= 278px/m 将其与加速度为9.8 m/s^2的px/ms^2转换回去,你会得到: 278 px/m * 9.8 m/s^2 * (1/1000) s/ms * (1/1000) s/ms ~= 0.00272 px/ms^2 因此,要模拟一个180厘米高的人有50个像素高的世界,您需要使用0.00272作为PhysicsJS y-加速度参数。

1
是的。=)我思考了几天,得出了类似的理解(你的更全面)。我还查看了源代码,并找到了一种方法,不仅可以使用我喜欢的单位,而且可以使每米像素比率可配置。这似乎是一种很好的缩放方式,可以实现其他功能。 下周我会有时间再处理它,并打算写几行代码并制作几个演示。然后我会更新我的问题... 非常感谢!每一点都让我的想法更清晰。 - slacktracer
嘿,我写了那几行代码:https://coderwall.com/p/ntb6bg 如果你有时间检查一下,我很想听听你的见解! - slacktracer

0

来自PhysicsJS基本用法 - 行为

// add some gravity
var gravity = Physics.behavior('constant-acceleration', {
    acc: { x : 0, y: 0.0004 } // this is the default
});

你可以控制重力的工作方式,但似乎没有提供单位参考。


但是为什么?0.0004 是什么? - slacktracer
这是你的世界;我相信决定权在你手中。 - adamdc78
那不可能是正确的。=) 如果我想模拟一些特定的阻力,我需要具体和一致的单位。return this.velocityDirection.mult(-0.5 * rho, this.dragCoefficient * this.area * this.body.state.vel.clone().normSq());如果我的面积是平方米(就像现在这样),而我的速度以每毫秒像素为单位(看起来是这样),那么我就会遇到问题。非常遗憾,这是个大问题。 - slacktracer
1
在这种情况下,您需要将您的区域转换为像素平方(不知道如何考虑缩放和显示分辨率),然后再将其传递给方法,是吗?我实际上没有使用过该库,但这就是我会做的。我希望我能更有用些。 - adamdc78
无论如何,谢谢你,@adamdc78。=)我还没有考虑过转换为像素...我不知道。我会试着理解它...看看是否有一种有效的方法来进行所有转换并保持与PhysicsJS的灵活性... - slacktracer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接