# Airframe geometry

The geometry an aeroplane is made of — a fuselage lofted along its own axis with a second deck on the crown, a swept and kinked wing you can sample anywhere — and the one mechanism on it that is really solved: a leg swinging about its trunnion with a side stay that folds.

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

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

## Notes

- Solved: the side stay, by the law of cosines. Everything else here is a loft or a mix — there is no lift, no drag, no load factor and no stall, and controlMix is a mixer rather than aerodynamics.
- Pure functions over plain objects: no React, no three.js, no dependencies. Angles are degrees on the surface and radians inside.

## Usage

```tsx
import {
  controlMix,
  fuselageRing,
  fuselageSection,
  gearRetraction,
  wingSurface,
} from "@/lib/robocn/airframe"

// The body at a station, and that station as a ring of world points.
const section = fuselageSection(-70)
section.crown            // the upper deck stands here
fuselageRing(section, 16)

// Every moving surface is a patch of one planform: a slat is 0 to 0.14 of the
// chord, a Fowler flap 0.73 to 1, between two fractions of the half-span.
wingSurface(0.1, 0.32, 0.73, 1)

// The stay's knee is the solve; everything else is the leg's own angle.
const leg = gearRetraction(0.4)
leg.knee                 // folded, and still exactly its two link lengths away
leg.reachable            // false only if the stay could not span the gap

// The rules a big aeroplane flies by, not aerodynamics.
controlMix({ roll: 8, configuration: 0.6 })
```

## API

| name | type | default | description |
| --- | --- | --- | --- |
| `fuselageSection(z, loft?)` | `(z: number, loft?: Partial<FuselageLoft>) => FuselageSection` | — | The body at one station: radius, centreline, crown, keel, and how much of the upper deck stands there. A nose ogive, a constant barrel and an upswept tail cone, continuous at both joins; outside the ends it is the end it is past, so a caller that over-runs gets a closed body rather than a negative radius. |
| `fuselageRing(section, steps?)` | `(section: FuselageSection, steps?: number) => Vec3[]` | — | That section as a closed ring of world points, crown first and round to starboard. The upper deck is a lobe added on the crown side and faded out by the equator, which also narrows the section slightly where it stands. |
| `wingStation(t, plan?)` | `(t: number, plan?: Partial<WingPlanform>) => WingStation` | — | The wing at a fraction of the half-span: distance out, height from the dihedral, leading and trailing edge, chord and built-in twist. The leading edge is one straight swept line while the chord collapses root to kink to tip, which is what gives a big jet its almost-unswept inboard trailing edge. |
| `wingSurface(from, to, chordFrom, chordTo, plan?)` | `(…) => Vec3[]` | — | A patch of that planform between two spanwise stations and two chord fractions, as four world points on the starboard side. Every moving surface the wing carries is one of these, so flaps, slats, ailerons and spoilers all track the same planform instead of drifting off it. `wingPanel` is the whole chord. |
| `gearRetraction(retraction, gear?)` | `(retraction: number, gear?: Partial<GearGeometry>) => GearPose` | — | One gear unit from 0 down-and-locked to 1 stowed. The leg is rigid and swings about its trunnion; the side stay is anchored to the structure at one end and pinned part-way down the leg at the other, so its knee is an elbow solve — two links and a known pair of ends. A stay that cannot span the gap clamps onto its own annulus and reports `reachable: false` rather than returning NaN. |
| `controlMix(command?)` | `(command?: ControlCommand) => ControlDeflections` | — | Pitch, roll, yaw, the flap lever and the speedbrake, mixed into every surface. Four rules a big aeroplane really keeps: the slats lead the flaps out; the outboard ailerons lock out once the flaps are up; the roll spoilers rise on the down-going wing only, while the speedbrake puts both sides up; and the stabiliser trims with the configuration. |
| `defaultFuselageLoft / defaultWingPlanform / defaultGearGeometry` | `const` | — | The dimensions the airliner ships with, in world units — x starboard, y up from the ground, z aft, nose at -z. |

## Source

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