---
title: "Quick Start Guide"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Quick Start Guide}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)
```

## Installation

```r
# 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:

```r
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.

```{r}
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:

```{r sun-earth-plot-with-sun, message = FALSE}
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:

```{r eval = FALSE}
animate_system(sim, fps = 15, duration = 5)
```

![](../man/figures/quick-start-earth-orbit-anim.gif)

`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:

```{r}
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:

```{r}
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:

```{r}
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](keplerian-elements.html) 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:

```{r}
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:

```{r}
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
```

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:

```{r eval = FALSE}
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()`:

```{r eval = FALSE}
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](the-physics.html)** — Understand the math behind the simulation
- **[Examples](examples.html)** — More complex systems including binary stars and the Kepler-16 system
- **[Unstable Orbits](unstable-orbits.html)** — Why most random configurations are chaotic
- **[3D Plotting](plotting-3d.html)** — Interactive 3D visualization with plotly
- **[Custom Visualization](custom-visualization.html)** — Build your own plots with ggplot2 and plotly
- **[Physical Constants](physical-constants.html)** — All built-in masses, distances, and speeds
- **[Roadmap](roadmap.html)** — Features being considered for future versions, plus a place to suggest your own
