# Tripod droid

A stubby three-legged survey walker that has to move its own mass onto the line between two feet before it can lift the third — and reports how much room it has left.

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

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

## Notes

- Three legs is the mechanism. Lift one and the base of support collapses from a triangle to a line, so the body has to be over that line before the foot leaves the floor. `solveTripod` schedules the load, the static condition puts the centre of mass at the load-weighted mean of the contacts, and that mean is where the body stands.
- How far it may move is not a magic number: it is whatever reach is left in a leg once a planted foot has been paid for. Creep fits inside it; amble asks the body to stand over a single foot, which it cannot reach, so the clamp bites and the margin goes negative. Longer links or a lower ride height buy the room back.
- Front elevation is the view it is drawn in. The slab is three stacked solids so the chamfer is geometry rather than paint, and the face marks are flat rectangles on the nose panel — they foreshorten in iso and collapse to a line in plan, which is what marks on a face do.
- Illustrative where it says so: the load ramp is a chosen schedule and not a ground-reaction solve, there is no mass or inertia anywhere, and the stub arms are counterweights in appearance only — they carry nothing in the solve. A negative margin means it could not hold that pose standing still, not that it has been simulated falling over.
- An original archetype — a three-legged survey walker — named for its job. No franchise, no insignia, no paint scheme; the default palette is the theme's and the label is the caller's.

## Usage

```tsx
import { TripodDroid } from "@/components/ui/tripod-droid"

<TripodDroid behavior="trundle" showSupport />

// Or scrub the gait and push the body over its feet yourself.
<TripodDroid gait="creep" stride={0.35} lean={{ x: 0.6, y: 0 }} view="iso" />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"front"` | Where the camera stands. One walker, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `behavior` | `"trundle" | "scurry" | "survey" | "settle" | "static"` | `"trundle"` | Trundle creeps about, wandering off course and back; scurry ambles flat out on a gait it cannot hold; survey turns on the spot; settle stands and breathes. |
| `gait` | `"stand" | "creep" | "amble" | "pivot"` | — | Footfall pattern. Omit and the behaviour picks one. |
| `stride` | `number` | — | Controlled gait cycle, 0–1. Supplying it stops the clock. |
| `speed` | `number` | `0.45` | Gait cycles per second. |
| `animate` | `boolean` | `true` | Off parks the machine at phase and stops rendering. A reduced-motion preference does the same. |
| `paused` | `boolean` | `false` | Freeze where it stands. |
| `phase` | `number` | `0` | Seconds of offset, so a row of machines breaks step. |
| `lean` | `Vec2 | null` | `null` | Controlled body offset over the feet, −1..1 on each axis. It beats the drag, and the gait still runs underneath. |
| `onLeanChange` | `(lean: Vec2) => void` | — | The lean a drag or a key moved it to, reported in controlled mode too. |
| `interactive` | `boolean` | `true` | Press and drag to push the body over its feet, or use the arrow keys; Home re-centres and End pushes it forward to the stop. Release eases it back into the gait. |
| `height` | `number` | — | Ride height 0–1. It is also a stability control: standing tall leaves less leg to move the body with, so there is less sway to walk on. |
| `step` | `number` | — | Foot travel, 0–1. |
| `lift` | `number` | `0.5` | Swing clearance, 0–1. |
| `heading` | `number` | — | Travel direction in degrees: 0 walks toward the nose, 90 to starboard. |
| `look` | `Vec2 | null` | `null` | Controlled optic aim in −1..1; overrides pointer tracking. |
| `track` | `boolean` | `true` | The slot optics follow the page pointer while look is null. |
| `showSupport` | `boolean` | `false` | Draw the support polygon, a ring at each loaded foot sized by its share, and the centre of mass. |
| `variant` | `"solid" | "outline" | "blueprint" | "wire"` | `"solid"` | How the machine is painted. Geometry never changes between variants. |
| `size` | `"xs" | "sm" | "md" | "lg" | "xl" | number` | `"md"` | Rendered width in pixels, or a step on the scale. |
| `showGround` | `boolean` | `true` | Draw the contact line or shadow beneath the droid. |
| `signal` | `"idle" | "ready" | "warning"` | — | Status-lamp state using neutral, accent, or shell colour; each component documents its visual default in the demo. |
| `label` | `string` | — | Optional technical caption under the drawing. |
| `color` | `string` | `var(--robot-shell)` | Body panels — the colour the machine reads as. |
| `accent` | `string` | `var(--robot-accent)` | Status colour: tip light, live tool, readouts. |
| `metal` | `string` | `var(--robot-metal)` | Bare machined parts: collars, bolts, tool bodies. |
| `dark` | `string` | `var(--robot-dark)` | Cast joints, base, shadow side. |
| `palette` | `Partial<RobotPalette>` | — | Override any subset of roles at once, including glow and grid. |

## Source

- `src/components/ui/tripod-droid.tsx`
