b2GravityController.prototype.Step = function (step) {
var i = null;
var body1 = null;
var p1 = null;
var mass1 = 0;
var j = null;
var body2 = null;
var p2 = null;
var dx = 0;
var dy = 0;
var r2 = 0;
var f = null;
if (this.invSqr) {
for (i = this.m_bodyList;
i; i = i.nextBody) {
body1 = i.body;
p1 = body1.GetWorldCenter();
mass1 = body1.GetMass();
for (j = this.m_bodyList;
j != i; j = j.nextBody) {
body2 = j.body;
p2 = body2.GetWorldCenter();
dx = p2.x - p1.x;
dy = p2.y - p1.y;
r2 = dx * dx + dy * dy;
if (r2 < Number.MIN_VALUE) continue;
f = new b2Vec2(dx, dy);
f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass());
if (body1.IsAwake()) body1.ApplyForce(f, p1);
f.Multiply((-1));
if (body2.IsAwake()) body2.ApplyForce(f, p2);
}
}
}
else {
for (i = this.m_bodyList;
i; i = i.nextBody) {
body1 = i.body;
p1 = body1.GetWorldCenter();
mass1 = body1.GetMass();
for (j = this.m_bodyList;
j != i; j = j.nextBody) {
body2 = j.body;
p2 = body2.GetWorldCenter();
dx = p2.x - p1.x;
dy = p2.y - p1.y;
r2 = dx * dx + dy * dy;
if (r2 < Number.MIN_VALUE) continue;
f = new b2Vec2(dx, dy);
f.Multiply(this.G / r2 * mass1 * body2.GetMass());
if (body1.IsAwake()) body1.ApplyForce(f, p1);
f.Multiply((-1));
if (body2.IsAwake()) body2.ApplyForce(f, p2);
}
}
}
}
这个if语句是为什么区分什么?
勘误: invSqr 应该是inverse-square 的简写,平方反比(1/r²),但据下文
f.Multiply(this.G / r2 / Math.sqrt(r2) * mass1 * body2.GetMass())
来看明显拼写错了,作者应该是想写inverse-cube立方反比(1/r³),但却误写成invSqr(inverse-square)。万有引力只适用于宏观尺度,随着粒子直径不断缩小,粒子间的万有引力不断缩水,计算出来的误差越来越大。为了修正这个偏差,GmM/r² =>GmM/r³、甚至GmM/r² =>GmM/r⁴。。。。直至粒子变成了分子原子进入电磁力的主导范围时,这种误差修正就被完全抛弃了。
因此第一个if分支,立方反比(1/r³)是模拟微粒(0.01m~)的运动情况;第二个if分支,平方反比(1/r²)就是正常的粒子(0.1m~10m)运动。
PS: 详细的物理解释请恶补下范德华力之类的粒子作用力系统