# Quick Start Guide

## Installation

    # Install from CRAN:
    install.packages("orbitr")

    # Or install the development version from GitHub:
    # install.packages("devtools")
    devtools::install_github("DRosenman/orbitr")

For 3D interactive plotting, you’ll also want:

    install.packages("plotly")

## Your First Simulation in 30 Seconds

`orbitr` is designed around a simple pipe-friendly workflow: create a system, add bodies, simulate, and plot.

    library(orbitr)

    create_system() |>
      add_body("Earth", mass = mass_earth) |>
      add_body("Moon",  mass = mass_moon, x = distance_earth_moon, vy = speed_moon) |>
      simulate_system(time_step = seconds_per_hour, duration = seconds_per_day * 28) |>
      plot_orbits()

That’s it — a 28-day lunar orbit in four lines. Here’s what each step does:

1. `create_system()` initializes an empty simulation with standard gravitational constant G.
2. `add_body()` places a body with a given mass, position, and velocity. All positions are in meters, velocities in m/s. The built-in constants (`mass_earth`, `distance_earth_moon`, etc.) save you from looking anything up.
3. `simulate_system()` runs the N-body integration forward in time. `time_step` is how many seconds per integration step, `duration` is the total time to simulate.
4. `plot_orbits()` produces a quick 2D trajectory plot using `ggplot2`.

## Customizing the Plot

By default, `plot_orbits()` returns a standard `ggplot` object for planar (2D) simulations and a `plotly` HTML widget for simulations with any 3D motion. (You can also force 3D rendering on planar data with `three_d = TRUE`.) Because the 2D case returns a regular ggplot, you can layer additional geoms, scales, themes, and labels onto it with `+` like any other ggplot.

A common annoyance is that the central body in a two-body system can be invisible: `plot_orbits()` draws each body as a `geom_path()` of its trajectory, and a much more massive body barely moves so its path is too small to see. The Sun in a Sun-Earth simulation is the classic example — it’s there, but its loop around the barycenter is well inside the Sun itself. The simplest fix is to drop a marker at the origin:

    sim <- create_system() |>
      add_sun() |>
      add_body("Earth", mass = mass_earth, x = distance_earth_sun, vy = speed_earth) |>
      simulate_system(time_step = seconds_per_day, duration = seconds_per_year)

    sim |>
      plot_orbits() +
      ggplot2::geom_point(
        data = data.frame(x = 0, y = 0),
        ggplot2::aes(x = x, y = y),
        color = "#00BFC4",
        size = 6
      ) +
      ggplot2::labs(title = "Earth-Sun Orbit")

This works because the Sun sits essentially at the origin throughout the simulation. For systems where the central body actually moves a noticeable amount, you’d want to pull its position from the simulation tibble instead of hardcoding `(0, 0)`.

## Watching the Orbit in Motion

Static plots are nice, but you can also play the simulation forward as an animation with `animate_system()`. By default each body leaves a fading wake of recent positions behind it:

    animate_system(sim, fps = 15, duration = 5)

`animate_system()` is the animated counterpart to `plot_system()` — it samples the simulation tibble down to roughly `fps * duration` evenly spaced frames, then renders them as a GIF using `gganimate`. Like the static plotters, it auto-dispatches to a 3D version (`animate_system_3d()`, an interactive `plotly` widget with a play button) the moment any body has non-zero Z motion. The 2D path requires the `gganimate` and `gifski` packages — install them with `install.packages(c("gganimate", "gifski"))`.

## Adding More Bodies

Since `orbitr` is a full N-body engine, you can add as many bodies as you want. Each one gravitationally interacts with every other.

For real solar system bodies, there are two ways to add them:

The manual way — use `add_body()` with explicit positions and velocities. This gives you full control and works for any body, real or fictional:

    create_system() |>
      add_sun() |>
      add_body("Earth", mass = mass_earth, x = distance_earth_sun, vy = speed_earth) |>
      add_body("Venus", mass = mass_venus, x = distance_venus_sun, vy = speed_venus) |>
      simulate_system(time_step = seconds_per_day, duration = seconds_per_year) |>
      plot_orbits()

Venus completes more than one full orbit in the same time Earth takes to go around once — you can see the inner orbit is both smaller and faster.

The easy way — use `add_sun()` and `add_planet()`, which use real masses and orbital data from JPL automatically. Any orbital element can be overridden for “what if” scenarios:

    create_system() |>
      add_sun() |>
      add_planet("Earth", parent = "Sun") |>
      add_planet("Mars",  parent = "Sun") |>
      simulate_system(time_step = seconds_per_day, duration = seconds_per_year * 2) |>
      plot_orbits(three_d = FALSE)

And `load_solar_system()` gives you the whole thing in one call:

    load_solar_system() |>
      simulate_system(time_step = seconds_per_day, duration = seconds_per_year) |>
      plot_orbits(three_d = FALSE)

Under the hood, these use Keplerian orbital elements — a way to describe orbits by their shape and orientation instead of raw positions and velocities. See Keplerian Orbital Elements for the full explanation.

## Removing Bodies

You can drop bodies from a system with `remove_body()`. This is handy when you want to start from `load_solar_system()` but don’t need every body:

    load_solar_system() |>
      remove_body(c("Pluto", "Moon")) |>
      simulate_system(time_step = seconds_per_day, duration = seconds_per_year) |>
      plot_orbits(three_d = FALSE)

`remove_body()` accepts a single name or a character vector and works anywhere in the pipe chain — before or after adding bodies, but always before simulating.

## The Output is Just a Tibble

`simulate_system()` returns a standard tidy tibble. You can use `dplyr`, `ggplot2`, `plotly`, or any other tool on it:

    sim <- create_system() |>
      add_body("Earth", mass = mass_earth) |>
      add_body("Moon",  mass = mass_moon, x = distance_earth_moon, vy = speed_moon) |>
      simulate_system(time_step = seconds_per_hour, duration = seconds_per_day * 28)

    sim
    #> # A tibble: 1,346 × 9
    #>    id       mass          x           y     z      vx          vy    vz  time
    #>    <chr>   <dbl>      <dbl>       <dbl> <dbl>   <dbl>       <dbl> <dbl> <dbl>
    #>  1 Earth 5.97e24         0         0        0   0        0            0     0
    #>  2 Moon  7.34e22 384400000         0        0   0     1022            0     0
    #>  3 Earth 5.97e24       215.        0        0   0.119    0.000571     0  3600
    #>  4 Moon  7.34e22 384382520.  3679200        0  -9.71  1022.           0  3600
    #>  5 Earth 5.97e24       860.        4.11     0   0.239    0.00229      0  7200
    #>  6 Moon  7.34e22 384330083.  7358065.       0 -19.4   1022.           0  7200
    #>  7 Earth 5.97e24      1934.       16.5      0   0.358    0.00514      0 10800
    #>  8 Moon  7.34e22 384242692. 11036262.       0 -29.1   1022.           0 10800
    #>  9 Earth 5.97e24      3438.       41.1      0   0.477    0.00914      0 14400
    #> 10 Moon  7.34e22 384120357. 14713454.       0 -38.8   1021.           0 14400
    #> # ℹ 1,336 more rows

Each row is one body at one point in time, with columns for position (`x`, `y`, `z`), velocity (`vx`, `vy`, `vz`), mass, body ID, and time.

## Saving and Sharing Systems

You can save a full system to disk and restore it later:

    save_system(sys, "my_system.rds")
    restored <- load_system("my_system.rds")

To share body data as a CSV — for collaborators, Python, or Excel — use `export_bodies()`:

    export_bodies(sys, "bodies.csv")

`save_system()` / `load_system()` preserves everything (bodies, gravitational constant, class) as an R object. `export_bodies()` writes a plain CSV with just the body table, which anyone can open.

## Next Steps

- The Physics — Understand the math behind the simulation
- Examples — More complex systems including binary stars and the Kepler-16 system
- Unstable Orbits — Why most random configurations are chaotic
- 3D Plotting — Interactive 3D visualization with plotly
- Custom Visualization — Build your own plots with ggplot2 and plotly
- Physical Constants — All built-in masses, distances, and speeds
- Roadmap — Features being considered for future versions, plus a place to suggest your own