最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - JS, Object following a circle - Stack Overflow

programmeradmin0浏览0评论

I'm trying to get an object to circle around another object. Not too hard, I figured. But it turns out the circle is a spiral... I'm probably using the wrong formula but I am not sure which one I should take instead...

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;

When you execute this code, it would appear to work. Each frame the object moves in an arc around it's parent object.

However, the arc gets bigger and bigger, increasing it's distance more and more.

What mistake am I making?

I'm trying to get an object to circle around another object. Not too hard, I figured. But it turns out the circle is a spiral... I'm probably using the wrong formula but I am not sure which one I should take instead...

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;

When you execute this code, it would appear to work. Each frame the object moves in an arc around it's parent object.

However, the arc gets bigger and bigger, increasing it's distance more and more.

What mistake am I making?

Share Improve this question asked Apr 27, 2012 at 9:50 JohanJohan 1,5571 gold badge11 silver badges17 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

You simply don't have infinite precision in your float values, and you don't have infinitely small angular steps. So this iterative calculum cannot be exact.

There is no exact iterative solution : if you try to improve the precision with your initial approach, you'll still get a divergence.

The solution is simply to pute each step pletely from the angulum, which is easy for a circle :

// 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);

@dystroy's solution is totally legit, but there is a way to constrain your iterative approach so that it doesn't spiral out of control.

Introduce a new variable, R, which is the fixed radius at which you want your object to circle its parent.

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);

Then you can add the constraint that the radius of the circle is fixed:

//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;

You could also apply the constraint after updating the position.

发布评论

评论列表(0)

  1. 暂无评论