I have one 3d object A and B in one game engine. Object A is a planet, and have infinity mass, and dont move. I have a radius constant that defines an fixed orbit sphere ( an sphere where I want the objectb to be at the edge of it ). And object B, is subject to random forces from colisions from other objects, so there is forces acting on it already. How to make object B to have the same distance from object B ( keep in the radius in the sphere ) just using forces ? I know there is some complex calculations on Jacobian equations but I am tryting to avoid that. Currently I am doing :
gravity_vector = planetcentercoordinate - objectBposition
distance_number = size ( gravity_vector ) --> just the distance of the two objects
IF distance_number>radius THEN gravity_vector = - gravity_vector --> invert the forces if the object pass the sphere orbit into the planet core
force = gravity_vector
If I just do this, the object goes into the direction of the orbit sphere as intend, but its just bouncing too much... There is another simple way to do it or maybe an correction on the force if the distance is smaller ?
An example in Javascript (some parts are omitted for brevity): I have a CelestialBody
function (a "class") that returns an object that represents a body in space (planet, star, etc...)
function CelestialBody(mass, velocity, mesh){
this.forceBetween = function(body){
var squareDistance = this.squareDistanceFrom(body);
var force = Constants.G * (this.mass * body.mass) / squareDistance;
return force;
};
this.addForceContribution = function(body){
var forceMagnitude = this.forceBetween(body);
var distance = this.distanceFrom(body);
var xDiff = body.getPosition().x - this.getPosition().x;
var yDiff = body.getPosition().y - this.getPosition().y;
var zDiff = body.getPosition().z - this.getPosition().z;
var xRatio = xDiff / distance;
var yRatio = yDiff / distance;
var zRatio = zDiff / distance;
var fx = forceMagnitude * xRatio;
var fy = forceMagnitude * yRatio;
var fz = forceMagnitude * zRatio;
var forceVector = new THREE.Vector3(fx, fy, fz);
this.acceleration.add(forceVector.divideScalar(this.mass));
};
this.updatePosition = function(delta){
if(!delta){
delta = Constants.DEFAULT_TIME_DELTA; // just to make debugging possible
}
this.velocity = this.velocity.add(this.acceleration.multiplyScalar(delta));
var tempVelocity = this.velocity.clone();
var nextPosition = this.getPosition().clone();
nextPosition.add( tempVelocity.multiplyScalar(delta) );
this.mesh.position.x = nextPosition.x;
this.mesh.position.y = nextPosition.y;
this.mesh.position.z = nextPosition.z;
this.acceleration = new THREE.Vector3(0, 0, 0);
};
}
In the main game loop, at every step, for every body, I take into account the gravitational force contribution of any other body and update the position accordingly:
for (var i = 0; i < celestialBodies.length; i++) {
for (var j = 0; j < celestialBodies.length; j++) {
if (celestialBodies[i] === celestialBodies[j]) {
continue;
}
celestialBodies[i].addForceContribution(celestialBodies[j]);
}
}
for (var i = 0; i < celestialBodies.length; i++) {
celestialBodies[i].updatePosition();
// check if the body is gone too far: if so, marks it for removal
if (celestialBodies[i].getPosition().distanceTo(new THREE.Vector3(0, 0, 0)) > Constants.REMOVAL_DISTANCE_THRESHOLD) {
celestialBodies[i].markedForRemoval = true;
}
}
The full code is here.