A trebuchet has no sights, no elevation screw and no powder charge. It has a bent nail.
The nail is the release pin: a finger on the end of the throwing arm with the sling’s open loop dropped over it, and the loop slides off when the sling has swung round to the finger’s angle. Bend the finger and you change when the stone goes, which is the only decision in the machine. Everything else — counterweight, arm ratio, sling length — is decided before the siege starts and cannot be touched between shots.
So this is a mechanic about one number, and the interesting thing about that number is that it behaves nothing like a dial should.
What is actually being solved
src/loose.mjs is three rigid bodies and three angles: the beam about its axle
(θ), the counterweight hanging on its link (φ), and the sling (ψ), all
measured from straight down. The kinetic energy is exact —
2T = (I + M b² + m a²) θ̇² + M c² φ̇² + m L² ψ̇²
− 2 M b c cos(θ−φ) θ̇φ̇ + 2 m a L cos(θ−ψ) θ̇ψ̇
— so the mass matrix and the forcing come out of the Lagrangian in closed form
and nothing is differentiated numerically. The stone starts in a trough on the
ground, which is a one-sided constraint y = 0 carried as a multiplier and
dropped the instant the ground would have to pull down instead of push up. A
rigidly bolted counterweight is the same code with b → b+c and c → 0, one
degree of freedom cheaper.
The machine as shipped: a 4 m beam on a 2.9 m axle, 3 m of throwing arm against 1 m of short arm, 500 kg on a 1 m link, a 5 kg stone on a 3.2 m sling, cocked with the arm 25° off straight down and its tip 181 mm above the ground.
Before believing any of it, scripts/measure.mjs checks the things a wrong
model gets wrong:
| check | result |
|---|---|
| energy drift over the whole throw | 2.3e-13 of the total |
trough constraint y = 0 while the stone is down | held to 2.2e-14 m |
| energy ledger at release closes | to 5.6e-14 |
| minimum sling tension (a rigid link may only pull) | +95.9 N |
| range, integrator step 1e-3 s against 5e-5 s | differs by 0.1 mm |
Release is refined by bisection down to the exact pin angle rather than whatever the fixed step happened to land on, because the whole piece is that one number and it must not be quantised by the integrator.
The pin points; it does not throw
Sweep the pin from −90° to +40° and the launch direction sweeps 129.9°, almost exactly one for one:
launch = −1.0131 · pin − 13.36 degrees worst residual 2.32°
and over −80° … 40°, which is the part of the dial where the machine is really throwing forward rather than straight up, that residual is 0.69° over 120° of travel. Meanwhile the release speed moves from 38.02 to 46.07 m/s — 19.2% across the whole dial, 13.9% across the useful part.
| pin | range (m) | release speed | launch | released at |
|---|---|---|---|---|
| −80° | 115.2 | 40.10 m/s | 67.4° | 6.08 m up |
| −60° | 193.3 | 43.17 m/s | 47.7° | 7.61 m up |
| −50° | 200.4 | 44.18 m/s | 37.6° | 8.16 m up |
| −30° | 142.9 | 45.43 m/s | 17.4° | 8.85 m up |
| −10° | 52.7 | 45.98 m/s | −3.0° | 9.03 m up |
| +20° | 14.5 | 45.94 m/s | −33.8° | 8.40 m up |
A trebuchet is a fixed-power cannon with a free turret. Nothing you can reach decides how hard the stone is thrown; the pin decides where it is pointed.
Which means two settings for every range but one
Point something at a fixed speed and the range is a hump. The peak here is 201.08 m at a pin angle of −52.25°, and every range short of it is reachable twice:
| range | lofted pin | its launch | flat pin | its launch | apart |
|---|---|---|---|---|---|
| 80 m | −87.5° | 73.7° | −17.0° | 4.1° | 70.5° |
| 120 m | −79.0° | 66.5° | −25.5° | 12.8° | 53.5° |
| 180 m | −65.0° | 52.7° | −39.5° | 27.0° | 25.5° |
| 195 m | −59.0° | 46.7° | −45.5° | 33.1° | 13.5° |
That is the mechanic, and it is nastier than it looks, because the top of the hump is not just flat, it is symmetric:
| off the best pin | ±1° | ±2° | ±3° | ±5° | ±10° |
|---|---|---|---|---|---|
| range cost | 0.07% | 0.27% | 0.60% | 1.6% | 6.4% |
The two sides agree to within 0.11% of the range out to ten degrees either way. Two effects are cancelling: turn the dial one way and the stone goes higher but slower, turn it the other and it goes flatter but faster, and near the peak those trade almost exactly. So a stone landing 15 m short is 15 m short in both directions at once. The artillery habit — it fell short, so give it more — is a coin flip, and following it with conviction walks the shot steadily away from the target. The demo lets you do exactly that, and then lets you measure the dial and see what you were doing.
45° is wrong, twice
The schoolbook answer for maximum range is 45°. The best shot this machine can take leaves at 39.90°, and the gap is two separate things stacked:
flat ground, free choice of angle 45.00°
same speed, but released 8.05 m up 43.88° (would carry 202.90 m)
what the machine actually wants 39.90° (carries 201.08 m)
The first 1.12° is ordinary: you are throwing from the top of a swing, 8 m up, and launching downhill always wants a flatter angle. The remaining 3.98° is the part you cannot calculate from the projectile alone — in this machine extra loft is not free, it has to be bought by releasing earlier, and releasing earlier costs release speed. The optimum lands where the two stop paying for each other. The machine gives up 1.82 m — 0.90% — to that coupling, which is the price of having a turret that is welded to the gun.
Where the counterweight’s energy goes
At the moment the stone leaves, the counterweight has given up 7749 J. The beam immediately takes 1120 J of that straight back, lifting its own throwing arm — 14.5% of the drop spent on the machine raising part of itself. What is left in play is 6629 J:
| destination | joules | share |
|---|---|---|
| stone, kinetic | 4835 | 72.9% |
| stone, lifted to 8 m | 395 | 6.0% |
| counterweight, still moving | 965 | 14.6% |
| beam, still turning | 435 | 6.6% |
| unaccounted | −3.7e-10 | −5.6e-14 |
Quoted the usual way — stone kinetic energy over the counterweight’s own drop — that is 62.4%.
The sling is what does it. The arm tip never exceeds 22.50 m/s in the whole throw and the stone leaves at 43.98 — 1.95× the fastest the arm ever went. At the instant of release the tip is down to 7.48 m/s, nearly six times slower than the stone: the arm has finished its work and handed everything to the line. And 46.4% of the 1.025 s throw happens before the stone has even left the trough — 0.475 s of being dragged along the ground while the arm swings from 25° to 65°.
The hinge is worth more than the counterweight
Bolt the same half tonne rigidly to the arm instead of hanging it from a hinge, change nothing else, and re-optimise the pin:
| counterweight | best pin | range | energy released | → stone | → still in the weight |
|---|---|---|---|---|---|
| hinged | −52.2° | 201.1 m | 6629 J | 72.9% | 14.6% |
| bolted | −52.5° | 123.7 m | 18131 J | 16.6% | 75.9% |
The bolted machine releases 2.74× as much energy and throws 38.5% shorter. It is not short of energy; it cannot get rid of it. A bolted weight is dragged around the arm’s circle and is still travelling fast when the stone goes, so three quarters of everything it gave up leaves with the machine instead of the stone. A hinged weight falls nearly plumb, arrives at the bottom, and stops — which is precisely how it hands its momentum over.
And you cannot buy the hinge back with mass:
| bolted counterweight | 500 kg | 750 kg | 1000 kg | 1500 kg | 2000 kg |
|---|---|---|---|---|---|
| best range | 123.7 m | 132.1 m | 136.6 m | 141.2 m | 143.6 m |
Four times the weight, bolted, reaches 143.6 m. Five hundred kilos on a hinge reaches 201.1.
Nothing on this machine can be tuned on its own
The sling wants to be about 1.07× the long arm, and every time you move it the best pin angle moves tens of degrees with it:
| sling | 2.4 m | 2.8 m | 3.0 m | 3.2 m | 3.6 m | 4.0 m | 4.4 m |
|---|---|---|---|---|---|---|---|
| of the arm | 0.80× | 0.93× | 1.00× | 1.07× | 1.20× | 1.33× | 1.47× |
| best pin | −44.3° | −47.0° | −49.3° | −52.3° | −60.0° | −71.0° | −85.8° |
| best range | 149.5 | 186.4 | 196.6 | 201.1 | 194.2 | 169.9 | 133.5 |
| range at the old best pin | 143.2 | 183.1 | 195.5 | 201.1 | 186.3 | 131.8 | 56.6 |
That last row is the whole warning. Lengthen the sling from 3.2 m to 4.0 m because longer slings throw further, leave the pin where it was, and the machine goes from 201 m to 132 m — worse, while being improved. Past 1.47× of the arm the sling goes slack before release, and the model says so by demanding a negative tension in a link that can only pull: those shots are reported, not believed.
One more thing falls out of the short end. The sling-to-arm angle normally climbs straight through the whip, so a pin angle picks one moment. Shorten the sling enough and it crests, falls back, and climbs again — and a pin set a quarter of a degree past that crest misses it entirely and waits for the next one:
| sling | 2.0 m (0.67×) | 2.4 m (0.80×) | 2.8 m (0.93×) | 3.2 m (1.07×) and up |
|---|---|---|---|---|
| steps in the dial | 1 | 1 | 0 | 0 |
At 2.0 m, pin −37.00° looses at 0.878 s from 5.08 m up and carries 48.4 m; pin
−36.75° looses 0.128 s later from 7.47 m up and carries 96.0 m. A quarter of a
degree, double the range. The machine as shipped has no such step anywhere on its
dial — cliffs() is there to keep it that way.
Reusing it
src/loose.mjs is framework-free and has no DOM in it.
import { machine, shoot, survey, bestPin, ledger, cliffs } from './loose.mjs';
const m = machine({ L: 3.2, M: 500, hinged: true });
const s = shoot(m, { pin: -52.25, dt: 2e-4, record: 1 / 240 });
// s.range, s.speed, s.launch, s.whipGain, s.minTension, s.frames
bestPin(m); // scan, not golden-section: range(pin) is not unimodal
survey(m, { step: 1 }); // the whole dial
ledger(m, s); // where the counterweight's energy ended up
cliffs(m); // pin angles where the dial jumps, if any
shoot takes checkEnergy when you want the drift reported, and record to
get frames back for drawing. dt: 2e-4 agrees with 5e-5 to eight significant
figures on range for a quarter of the steps; the demo runs at 2.5e-4 and
surveys the dial at 6e-4.
Two things to know if you change the geometry. The cocked arm tip has to be at
least as close to the ground as the sling is long, or initial() throws rather
than quietly starting with a slack sling. And minTension is not decoration: a
shot that reports a negative one is outside what a rigid massless link can
represent, and its range is not a number anyone should quote.




