无法阻止粒子过冲

Can't stop the particles from overshooting

我正在尝试创建一个简单的粒子模拟。粒子有静止的和运动的两种。静态粒子将移动的粒子吸引到它们的中心。静态粒子有一个强度属性,它决定了它们拉动移动粒子的力度

var angle:Number = Math.atan2(moving.y - static.y , moving.x - static.x);
var dist = Point.distance(new Point(moving.x,moving.y) , new Point(static.x,static.y));

moving.velX += Math.cos(angle + Math.PI) * static.strength / dist;
moving.velY += Math.sin(angle + Math.PI) * static.strength / dist;

问题是当一个粒子刚刚通过中心时,距离非常小,导致速度值非常大。

我在计算速度之前额外检查了距离。

if (dist < 1)
    dist = 1;

但问题依然存在。我想不出问题。

这是超调发生的快照。

普通力场是用距离的平方作为修饰符,你这里用的是距离的单次幂,当然力场表现不同。您应该将 var dist 行更改为以下内容:

var dist:Number = (moving.x-static.x)*(moving.x-static.x) + (moving.y-static.y)*(moving.y-static.y);

这样 dist 将保持实际距离的平方,因此除以 dist 将为您提供正确的力场配置。

并且,请重命名 static,因为它是 AS3 中的保留字。

您可能在 运行 dist 计算之前或 运行 vel 计算之后声明 dist 值。相反,请确保您正在执行的 dist 检查是在 dist 计算和 vel 计算之间。 Vesper 也是正确的,因为要获得正确的力效果,它应该使用距离的平方。但即使这样做,您仍然会得到不希望的(尽管在数学上完全准确)结果。

var angle:Number = Math.atan2(moving.y - static.y , moving.x - static.x);
var dist = Point.distance(new Point(moving.x,moving.y) , new Point(static.x,static.y));

if (dist < 1) dist = 1; // just make sure your constraint goes here.

moving.velX += Math.cos(angle + Math.PI) * static.strength / dist / dist; // this uses dist squared
moving.velY += Math.sin(angle + Math.PI) * static.strength / dist / dist; // but don't use this method in addition to Vesper's or you'll have dist to the power of 4.