JS,Object跟随一个圆圈

时间:2012-04-27 09:50:10

标签: javascript math animation canvas geometry

我正试图让一个物体围绕另一个物体。我想,并不太难。但事实证明这个圆圈是螺旋式的...我可能使用了错误的公式,但我不确定应该选择哪一个......

var dx = this.x - this.parent.x,
    dy = this.y - this.parent.y,
    r = Math.atan2(dy, dx);

this.x = Math.sin(r) * this.speed + this.x;
this.y = (Math.cos(r) * this.speed * -1) + this.y;

执行此代码时,它似乎可以正常工作。对象围绕其父对象以弧形移动的每个帧。

但是,弧越来越大,越来越远。

我犯了什么错误?

2 个答案:

答案 0 :(得分:5)

您的浮点值中没有无限精度,并且没有无限小的角度步长。所以这个迭代计算不可能是精确的。

没有确切的迭代解决方案:如果您尝试使用初始方法提高精度,您仍然会出现分歧。

解决方案就是完全从角度计算每一步,这对于一个圆圈很容易:

// init part, set your own values
var a = 0; // in radian
var r = 100; // radius, in pixels for example
var da = 1; // in radian. Compute this (once!) using r if you like to use an absolute speed and not a radial one


// each modification
a += da
x = r*Math.sin(a);
y = r*Math.cos(a);

答案 1 :(得分:2)

@dystroy的解决方案完全合法,但有一种方法可以限制你的迭代方法,使其不会失控。

引入一个新变量R,它是您希望对象圈出其父级的固定半径。

var hypot = function(x, y) { return Math.sqrt(x*x + y*y); };
//Run this code only once!
var R = hypot(this.x - this.parent.x, this.y - this.parent.y);

然后你可以添加圆的半径固定的约束:

//your original code
var dx = this.x - this.parent.x,
    dy = this.y - this.parent.y,
    r = Math.atan2(dy, dx);

//apply constraint:
//calculate what dx and dy should be for the correct radius:
dx = -R * Math.cos(r);
dy = -R * Math.sin(r);

//force this.x, this.y to match that radius.
this.x = this.parent.x + dx;
this.y = this.parent.y + dy;

//the radius will still be off after your update, but
//the amount by which it is off should remain bounded.
this.x = Math.sin(r) * this.speed + this.x;
this.y = (Math.cos(r) * this.speed * -1) + this.y;

您也可以在更新位置后应用约束。