Sweeping a Rock You Can No Longer Touch
Fran told me sweeping doesn’t speed the rock up. That bothered me, because it plainly does something — a swept stone runs farther and holds its line. What the brooms actually do is lower the friction under a rock you’re no longer allowed to touch. The throw is finished the instant the handle leaves your hand. After release the only knob left is the ice itself.
That’s a control problem with a mean constraint: the actuator is one-sided. You can shed drag by sweeping, but you can’t put it back. And you don’t sweep a little — the skip yells “hurry hard” or “off,” and the brooms are down or up. That’s bang-bang control, the on/off logic a thermostat runs on, except a thermostat can push the temperature both ways and here you can only ever pull in one direction.
So the entire tactic is: throw a hair light, then sweep to carry the stone the rest of the way. Watch where the rock would coast to a stop if you left it alone. If that projected resting point is short of the button, drop the brooms. The instant it’s on line to reach the button, stand up and let the pebble take over.
fun main() {
val target = 30.0 // distance to the button, in metres
val hardDrag = 0.55 // full ice friction, unswept
val sweptDrag = 0.35 // friction once the brooms go down
val dt = 0.1
var pos = 0.0
var vel = 5.5 // fixed the moment the rock is released
while (vel > 0.01) {
val coast = pos + vel * vel / (2 * hardDrag) // stop point if we do nothing
val drag = if (coast < target) sweptDrag else hardDrag
vel -= drag * dt
pos += vel * dt
}
println("Rock stopped at %.1f m (button at %.1f)".format(pos, target))
}
Each tick asks the question the sweepers ask: where does this stop if we quit now? The projected stop is just v²/(2a), the schoolbook stopping distance. Short of the target, drop to the swept friction; otherwise leave the pebble alone.
fvariable pos
fvariable vel
30e fconstant target
0.55e fconstant hard \ full ice drag, unswept
0.35e fconstant swept \ drag while sweeping
0.1e fconstant tick
: coast ( -- f ) pos f@ vel f@ fdup f* hard 2e f* f/ f+ ;
: drag ( -- f ) coast target f< if swept else hard then ;
: step
vel f@ drag tick f* f- vel f!
pos f@ vel f@ tick f* f+ pos f! ;
: throw-rock
0e pos f! 5.5e vel f!
begin vel f@ 0.01e f> while step repeat
." Rock stopped at " pos f@ f. ." m" cr ;
throw-rock
I wrote the second version in Forth because on/off controllers like this one lived inside 1980s embedded hardware, and Forth was what you reached for when the controller had four kilobytes and no operating system underneath it. The logic is identical — read the state, project the stop, pick one of two drags — and it fits in a dozen words.
Both land the stone within a few centimetres of thirty metres, and neither one ever touched the throw. My model only steers distance, though. On real ice the brooms also straighten the curl — flatten that sideways drift I still can’t explain — and that’s a second axis I haven’t worked out how to write down. Fran says you learn to feel it. I fell over six times, so I’m not there.