无法阻止粒子过冲
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.
我正在尝试创建一个简单的粒子模拟。粒子有静止的和运动的两种。静态粒子将移动的粒子吸引到它们的中心。静态粒子有一个强度属性,它决定了它们拉动移动粒子的力度
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.