# Transmission geometry

Where the flexible thing goes, and where the teeth are: gear outlines and mesh phase, assembly-valid planetary trains, taut belt paths, and an energy chain over its bend.

> For the complete index, see [llms.txt](https://robocn.dev/llms.txt). A Markdown version of any page is available by appending `.md` to its URL or by sending an `Accept: text/markdown` header.

## Install

```bash
bunx --bun shadcn@latest add https://robocn.dev/r/transmission-geometry.json
```

Registry item: `transmission-geometry` · [`https://robocn.dev/r/transmission-geometry.json`](https://robocn.dev/r/transmission-geometry.json)

## Notes

- Invariants the tests hold it to: a planetary train only comes back if it assembles and its reduction is exactly 1 + ring/sun; meshing gears counter-rotate at −N₁/N₂ and present a tooth to a space at the line of centres; a belt round two equal pulleys is 2 × centres + 2πr and the segments always add to the total; and a chain keeps its link count and pitch at every travel while its bend moves at exactly half the carriage.
- No dynamics anywhere: no torque, no belt tension, no backlash, no friction, no efficiency.
- Pure functions over plain objects. No React, no dependencies beyond the vector helpers.

## Usage

```tsx
import { planetaryTrain, planetaryPose, beltLayout } from "@/lib/robocn/transmission"

const train = planetaryTrain(18, 12, 3)   // { sun: 18, planet: 12, ring: 42, ratio: 3.33 }
const pose = planetaryPose(train, 140)    // carrier, planet bearings and spins, held ring

const belt = beltLayout([{ x: 0, y: 0, radius: 20 }, { x: 70, y: 0, radius: 8 }])
belt.length // spans plus wraps
```

## API

| name | type | default | description |
| --- | --- | --- | --- |
| `gearPath` | `(teeth, pitchRadius, options?) => string` | — | One gear's outline, tooth zero centred on the +x axis so a group rotate() is the gear's own angle. With a rim, the teeth point inward and the path is an annulus to be filled even-odd: a ring gear. |
| `meshAngle` | `(driverTeeth, driverAngle, drivenTeeth, bearing, internal?) => number` | — | The angle that puts the driven gear's teeth in the driver's spaces, given where it sits. Differentiating it gives the ratio: −N₁/N₂ externally, +N₁/N₂ for a pinion inside a ring. |
| `planetaryTrain` | `(sunTeeth, planetTeeth, planets) => PlanetaryTrain` | — | Tooth counts that actually assemble: ring = sun + 2 × planet, (sun + ring) divisible by the planet count, and planets capped so neighbours clear. Returns the reduction 1 + ring/sun. |
| `planetaryPose` | `(train, sunAngle) => PlanetaryPose` | — | Where every member of a fixed-ring train stands: the carrier at the reduction, each planet's bearing and spin, and the ring — which comes out constant, as a held ring must. |
| `beltLayout` | `(pulleys) => BeltLayout` | — | The taut path round a loop of pulleys taken in order: external tangents, a wrap arc on each, the total length and one path string. Two equal pulleys give 2 × centres + 2πr. |
| `beltSample` | `(layout, distance) => { x, y, heading }` | — | A point on the belt and the direction it is travelling, at an arc length. Wraps whole laps, which is how belt teeth march. |
| `carrierLinks` | `(travel, geometry) => CarrierPose` | — | An energy chain folded over itself: link placements at constant pitch along a fixed-length path, plus where the fold sits — at half the carriage, because the length cannot change. |

## Source

- `src/lib/robocn/transmission.ts`
