# Epicycles

> A chain of turning circles whose end draws a closed path, as in the 3Blue1Brown Fourier series. fourier(path, samples, terms) resamples the path along…

Page: https://fframes-kit.pages.dev/docs/math/epicycles/
Cargo feature: `math` (`fframes-kit = { version = "..", features = ["math"] }`)

A chain of turning circles whose end draws a closed path, as in the 3Blue1Brown Fourier
series. `fourier(path, samples, terms)` resamples the path along its length and returns the
largest terms first, centered on the path's mean point (y up). `Epicycles` places them at
`center` in units of `ui.space`, with `scale` units per unit of the path. `turns` (a tracker)
is how far the series has turned. The trace is what the end drew in the last `trace_length`
turns (1 keeps one full turn, the whole drawing). The circles and vectors draw with `enter` and
leave with `exit`; the trace stays. Gallery scenes:
`Epicycles`, and `FourierWord`: seven chains, one per letter, draw `fframes` from the glyph
outlines of `text_outline::outline`.

Gallery clip of `Epicycles`: https://fframes-kit.pages.dev/media/scenes/Epicycles-fc55884a.mp4

Gallery clip of `FourierWord`: https://fframes-kit.pages.dev/media/scenes/FourierWord-64e27462.mp4

```rust
use fframes::animation::KeyFramesAnimation;
use fframes_kit::prelude::*;
use fframes_kit::kits::math::{Term, fourier};

fn figure<'a>(
    ui: &mut Ui<'a, '_, '_>,
    terms: &'a [Term],
    turns: &'a KeyFramesAnimation<f32>,
) -> Svgr<'a> {
    ui.show(Epicycles {
        terms,
        turns: turns.into(),
        ..ui.defaults()
    })
}

let heart = Heart { height: 5.0, ..Heart::default() };
let terms = fourier(&heart.path(), 513, 40);
assert_eq!(terms.len(), 40);
assert!(terms[0].amplitude() >= terms[1].amplitude());
```

## API

Components are plain structs. Set the fields you need and fill the rest with `..ui.defaults()`: the defaults below come from the current theme (`theme.` values are fields of `Theme`).

### Epicycles

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `terms` | `&[Term]` | `&[]` | The circles, largest first, from `fourier`; each has a frequency, an amplitude and a phase. |
| `center` | `(f64, f64)` | `(0.0, 0.0)` | Where the series' origin sits, in units of `ui.space` (y up). |
| `scale` | `f64` | `1.0` | Units of `ui.space` for one unit of the series. |
| `turns` | `ValueTracker` | `0.0.into()` | How far the series has turned, in full turns of its slowest circle; a tracker to animate. |
| `circles` | `bool` | `true` | Draws the outline of each circle when `true`. |
| `vectors` | `bool` | `true` | Draws the arm of each circle, from its centre to its rim, when `true`. |
| `circle_color` | `Color` | `theme.colors.muted` | Colour of the circle outlines. |
| `vector_color` | `Color` | `theme.colors.text` | Colour of the arms. |
| `trace_color` | `Color` | `theme.colors.highlight` | Colour of the path the end of the chain draws and of the dot at its head. |
| `stroke_width` | `f32` | `theme.stroke.thin` | Line width in pixels of the circles and arms. |
| `trace_width` | `f32` | `theme.stroke.thick` | Line width in pixels of the trace. |
| `trace_length` | `f64` | `1.0` | How many turns of the end's path stay drawn; `1.0` keeps one full turn, the whole drawing. |
| `enter` | `Option<EnterAnim>` | `None` | How the circles and arms appear; `None` shows them from the start. |
| `exit` | `Option<ExitAnim>` | `None` | How the circles and arms leave at the end of its container; `None` stays (the trace stays regardless). |

Feature `math` · [Source](https://github.com/khanhthanhdev/fframes-kit/blob/main/fframes-kit/src/kits/math/epicycles.rs#L102)
