Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS, Object following a circle

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?

like image 466
Johan Avatar asked Apr 27 '12 09:04

Johan


People also ask

What is the area and circumference of a circle in JavaScript?

JavaScript: Area and circumference of a circle In geometry, the area enclosed by a circle of radius r is πr2. Here the Greek letter π represents a constant, approximately equal to 3.14159, which is equal to the ratio of the circumference of any circle to its diameter. The circumference of a circle is the linear distance around its edge.

What is an object in JavaScript?

JavaScript objects are containers for named values called properties or methods. Spaces and line breaks are not important. An object definition can span multiple lines: The name:values pairs in JavaScript objects are called properties: Objects can also have methods.

What is the circumference of a circle?

The circumference of a circle is the linear distance around its edge. Why is the area of a circle of a circle pi times the square of the radius? Previous: Write a JavaScript program to create a Clock. Next: Write a JavaScript program to sort an array of JavaScript objects.

What is the name of the values pairs in JavaScript objects?

The name:values pairs in JavaScript objects are called properties: Objects can also have methods. Methods are actions that can be performed on objects. Methods are stored in properties as function definitions. A method is a function stored as a property. In a function definition, this refers to the "owner" of the function.


2 Answers

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 compute each step completely 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);
like image 138
Denys Séguret Avatar answered Oct 19 '22 16:10

Denys Séguret


@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.

like image 2
ellisbben Avatar answered Oct 19 '22 16:10

ellisbben