# Batting rig

A bat on a solved swing arc meeting a pitched ball, with the collision itself solved: effective mass falls away from the sweet spot, so contact off the end hands the ball back less than it brought.

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

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

## Notes

- Solved: the collision. `1/M = 1/m + d²/I` is the mass the ball meets, `v_bat = ω·r` is what the barrel is doing, and `v_out = ((e·M − m)·v_pitch + M(1 + e)·v_bat)/(M + m)` is what the ball leaves with. The sweet spot is where that peaks, found by sampling the barrel rather than declared — move the swing rate and it moves.
- Solved too: the contact point, which follows from geometry alone. The bat can cross the line at exactly one angle, so `r·cos θ = −stance`, and standing closer jams it on the handle while standing off puts it on the end. The exit ray leaves along the face normal, which is the direction the barrel is travelling.
- Illustrated: the shape of the swing through the zone, which is an eased sweep and not a torque model; and the ball's line in, which is straight because a pitch is `robot-baseball`'s job.

## Usage

```tsx
import { BattingRig } from "@/components/ui/batting-rig"

// Where it stands decides where on the barrel the ball arrives.
<BattingRig stance={34} swingRate={0.9} />

// Or walk the bat through the zone yourself, which stops the loop.
<BattingRig swing={0.52} onSwingChange={setSwing} interactive />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `swing` | `number` | — | Phase through the swing, 0 at the load and 1 through the follow. Supplying it stops the loop. |
| `onSwingChange` | `(swing: number) => void` | — | Fires while it is dragged or keyed, so interaction works in controlled mode too. |
| `behavior` | `"swing" | "load" | "check" | "static"` | `"swing"` | What it does with nobody driving it. `load` and `check` both hold short of contact. |
| `stance` | `number` | `34` | How far the rig stands off the line, 22 to 44. This is the mechanism: the bat crosses the line at one angle only, so where it stands decides where on the barrel the ball arrives. |
| `swingRate` | `number` | `0.9` | Revolutions a second through the zone. It moves the sweet spot, because the barrel's speed is ω·r. |
| `showSweetSpot` | `boolean` | `true` | Ring the contact that would do the most with this swing, and dot the one it is actually making. |
| `showBall` | `boolean` | `true` | Draw the ball on its line in, and on the exit ray out. |
| `interactive` | `boolean` | `false` | Hand it to a person: drag across to walk the bat through the zone, or focus it and use the arrow keys. |
| `label` | `string` | — | Optional technical caption under the drawing. |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"plan"` | Where the camera stands. One machine, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `speed` | `number` | `0.5` | Swings 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. |
| `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. |
| `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/batting-rig.tsx`
