# Spine kinematics

The travelling-wave body solver behind the fish and the snake: a serpenoid curve with taper, steady turn, and ground clearance.

> 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/spine-kinematics.json
```

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

## Notes

- Integrating a tangent angle rather than displacing joints is what keeps every link exactly the same length at every phase — the invariant the tests assert.
- A crest travels head to tail as phase rises. Run phase backwards to reverse it. No thrust, drag or friction is modelled.

## Usage

```tsx
import { solveSpine, spineOutline } from "@/lib/robocn/spine"

const pose = solveSpine({ segments: 14, phase: 0.3, amplitude: 0.7, waves: 1.4, taper: 0.8 })
pose.joints // position, angle, s, clearance, contact
spineOutline(pose, (s) => 12 * (1 - s)) // the hull, as one path
```

## API

| name | type | default | description |
| --- | --- | --- | --- |
| `solveSpine` | `(options?: SpineOptions) => SpinePose` | — | Walks the joints off a travelling tangent angle from the nose backwards. The nose sits at the origin pointing along +x, with the body running back toward −x. |
| `SpineOptions` | `{ segments?, length?, phase?, amplitude?, waves?, taper?, turn?, lift? }` | — | Segments 3–24, amplitude 0–1 (1 is 52° of swing), waves 0.25–3, taper −1..1, turn −1..1 (1 is a half circle), lift 0–1 (up to 7 units of clearance). |
| `SpineJoint` | `{ position: Vec2, angle, s, clearance, contact }` | — | Angle is the body's heading at that joint in degrees; s runs 0 at the nose to 1 at the tail; contact means the joint is on the ground plane. |
| `spineOutline` | `(pose, halfWidth: (s) => number, round?) => string` | — | The joints offset either side by a width profile and closed into one SVG path — the hull, built from the solved spine rather than drawn beside it. |
| `spineLimits` | `{ swing: 52, turn: 180, clearance: 7 }` | — | What amplitude, turn and lift of 1 mean in degrees and world units. |

## Source

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