# Three-Body Orbit

The three-body problem is a classic orbital dynamics situation. You have three bodies, each with significant mass, all interacting gravitationally. This turns out to be a chaotic system, with no general closed-form solution. There are however a few stable configurations of the three-body problem.

In this tutorial, we will model one of the stable configurations from R. A. Broucke's technical report "Period Orbits in the Restricted Three-Body Problem with Earth Moon Masses".

#### Import Elodin and JAX

Our first step is to import Elodin and Jax into our environment:

```
= 1.0 / 120.0
```

`SIM_TIME_STEP`

value is the duration of each tick in the simulation.

#### Add 1st & 2nd Body

Before we can do anything we'll need an instance of a World, and with that we can spawn our first entities:

```
=
=
=
=
```

#### Add a basic system

Let's bring in the simplified earth gravity system we just used in the ball example:

```
return +
```

#### Let's try running the simulation

But first, let's add a view port so we can observe the world:

```
```

Now, we're ready to start simulating:

```
=
=
```

At this point you should have a running simulation, with two bodies that simply fall just like the ball example. However we don't want a simulation of basic earth gravity, but instead we want the bodies to interact which each other gravitationally like planetary bodies, so let's update our system for that next.

#### Setup Gravity Constraints

The gravitational force between two bodies is given by Newton's law of universal gravitation: $$ F_{ba}=-G\frac{m_bm_a}{|r_{ba}|^3}{r}_{ba} $$

Notice how we're using the Vector form of Newton's law, instead of the more well known scalar form. This is because we're working in a 3D space. Sometimes you may have to convert between the two forms yourself.

Let's model this as a system that iterates over all gravity edges in a graph of connected bodies and calculates the forces between them. Modeling with graphs and edges is a more advanced Elodin API, review the documentation for it here.

```
# Set the gravitational constant for Newton's law of universal gravitation
= 6.6743e-11
# Define a new "gravity edge" component type
=
# Define a new "gravity constraint" archetype using the gravity edge component
:
=
# Replace our simple system with one that applies gravity by iterating over
# all gravity edge components, accessing the positions and inertias of both edges
# Create a fold function to take an accumulator and the query results for the
# left and right entities, and apply Netwon's law of universal gravitation:
= -
=
=
=
= * * * /
# returns the updated force value applied to the left entity this tick
return
return
# Add the gravity constraint entities to the world
```

Also let's update the initial mass of our two bodies with the gravitational constant, this will give them a mass more representative of a planetary body:

```
= ,
```

Go ahead and run the simulation again, and you should see the two bodies interacting gravitationally.

You'll want to make sure to always keep the `six_dof()`

and `w.run()`

calls at the end of your script.

#### Add the Third Body

What's a gravitational system without a third body? Let's add a third body to the system.

```
=
```

If you run the simulation now, you'll see the three bodies interacting gravitationally. However, you'll notice that the it's a bit unstable.

#### A stable starting configuration

There are many known stable configurations for three-body systems, one of the most famous being the Lagrange points. For our first attempt we'll reference the Brouke R 7 configuration, which is a stable configuration for three bodies of equal mass.

Go ahead and update the starting values for our three bodies to the following:

```
=
=
=
```

Start the simulation again, and you should see the three bodies in a stable configuration.

#### Add some gizmos

Sometimes it can be helpful to visualize the forces acting on the bodies and their movements in 3D space. Add these two lines to see a few options in action:

```
```

Start the simulation again to see the gizmos in action.

#### Checking your work

And that's it! You can now run the simulation and see the three bodies orbiting around each other in a stable configuration. If you'd like to check your work, you can use the following command to generate the matching template code:

```
```

#### Make it fancy

Thanks to the amazing work done here, you can easily try a variety of stable configurations for the three-body system. Let's take the full set of Broucke's stable configurations and randomly select from them on each run of the simulation, for fun.

Add a few new imports to the top of your script, as well as fetching the JSON data from the URL and selecting a random orbit:

```
# URL of Bourke's stable orbits JSON data
=
# Fetch data and select a random orbit
=
# Example resulting object:
# {
# "name": "Broucke A 1",
# "url": "http://three-body.ipb.ac.rs/bsol.php?id=0",
# "pos": [
# [-0.9892620043, 0.0],
# [2.2096177241, 0.0],
# [-1.2203557197, 0.0]
# ],
# "vel": [
# [0.0, 1.9169244185],
# [0.0, 0.1910268738],
# [0.0, -2.1079512924]
# ]
# },
```

Then update your body creation to use the randomly selected orbit values for each of the three bodies:

The stable orbits are all in the x-y plane, so we set the z element of the position and velocity to 0.0.

```
=
=
=
=
=
=
=
=
=
```

And voila, you have a randomly selected stable three-body system!

#### Going further

You'll notice all of the simulations we've done here are in the x-y plane. As a further exercise, you could try to extend what you've learned here to find and apply the starting configurations for stable three-body systems in all three dimensions.

Post what you discover in the Elodin Discord!