Satellite : Placing a 3D object into Orbit around a Target

Orbiting around a fixed axis

Creating the 3D object

For starters, let’s create a simple 3D object in our scene. In this example, a sphere. It isn’t necessary to attribute a position to it for the moment!

// sphere
const geometry = new THREE.SphereGeometry( 1, 32, 32 );
const material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: false } );
sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );

Calculating the orbital position with Cosinus, Sinus and Clock

We will use the mathematical functions Cosinus and Sinus, respectively Math.cos() and Math.sin() to place our 3D object into orbit.

At each execution of our principal loop, it is necessary to update the object’s position based on elapsed time. To keep an eye on the clock, we use the Three.JS class Clock .

The method getDelta of the Clock class, is used to obtain the number of seconds elapsed since the last execution of the method.

The property elapsedTime of the class Clock keeps track of the total number of seconds elapsed since the start of the application. This is the value that we will use to calculate the position of the object in orbit as a function of time.

At each execution of the main loop, we calculate the position of the object in orbit :

function animate()
{
    //time tracking
    var delta = clock.getDelta();
    var elapsed = clock.elapsedTime;
    
    //sphere position
    sphere.position.x = Math.sin(elapsed/2) * 3;
    sphere.position.z = Math.cos(elapsed/2) * 3;

    [...]
}

We want to gravitate the 3D object to the Y axis :

We calculate the position on the X axis with Math.sin() of the elapsed time, then the position on the Z axis with Math.cos() of the elapsed time.

Placing an orbit around a target in motion

It is also possible to apply these concepts to place an orbit around a moving target!

Let’s create a second 3D object, like this cube :

//satelite
const geometry_satelite = new THREE.BoxGeometry( 0.4, 0.4, 0.4 );
const material_satelite = new THREE.MeshNormalMaterial( {  flatShading: true } );
satellite = new THREE.Mesh( geometry_satelite, material_satelite );
scene.add( satellite );

We want to make this new object orbit around the sphere in motion from the previous example. It is therefore necessary to include the position of the latter in the calculation of the satellite’s position, at each execution of the principal loop.

function animate()
{
    //time tracking
    var delta = clock.getDelta();
    var elapsed = clock.elapsedTime;
    
    //sphere position
    sphere.position.x = Math.sin(elapsed/2) * 3;
    sphere.position.z = Math.cos(elapsed/2) * 3;
    
    //satellite
    satellite.position.x =  sphere.position.x + Math.sin(elapsed*2) * 2;
    satellite.position.z = sphere.position.z + Math.cos(elapsed*2) * 2;
    satellite.rotation.x += 0.4 * delta;
    satellite.rotation.y += 0.2 * delta;
    
    requestAnimationFrame( animate );
    controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
    renderer.render( scene, camera );
}

Final result

See the Pen Gravitation by Thomas (@thomassifferlen) on CodePen.