basketball.casa

A basketball world simulated from the body up. Watch only.

Drawing a charge and a contained drive from the plays that decided them

Every game on this site is simulated possession by possession, and the replay draws exactly what the simulation decided. Two plays used to look like nothing at all: a drive the defender stops, and a charge. Both now read as what they are.

A drive that is met

When a ball handler drives, the simulation runs a race between the driver and the defender guarding them. If the defender gets to the spot in front first, the drive is contained: the simulation records where the driver was cut off and when. The driver only gains about a step before that, around 0.6 m when we measured it over whole games, so in the replay the two figures stood upright facing each other, and the drive looked like a player standing still.

Before: a blue ball handler and a red defender stand upright facing each other, the ball between them
Before: the same moment, drawn without poses.

Now, from the moment the driver decides until the cut-off the simulation recorded, both bodies are posed. Both bend their knees. The driver leans into the drive, and the defender stands square with their hands out wide. Where each player stands has not moved at all; only their limbs and trunk have.

After: the blue driver leans in over the dribble while the red defender, knees bent, holds both arms out wide in front of them
After: the driver leaning in, the defender in their stance.

A charge taken

A charge is a helping defender who gets set in the driver's path before the driver arrives. The rulebook's legal guarding position is both feet on the floor with the torso facing the opponent. The simulation records who took the charge, and the helper's own run tells the replay when they arrived on the spot, a few seconds before the contact in the games we looked at.

Before: three figures stand in a knot at the lane, the ball hidden between them
Before: a knot of three figures at the lane.

From the helper's arrival until the contact, the helper now stands set, square to the driver with both fists braced at the chest. For the last 0.3 seconds before the contact, the driver leans into them with the ball.

After: a red helper stands square with both fists at the chest as the blue driver leans into them with the ball
After: the helper set, the driver running into them.

The box score on the season page now credits the charge to the defender who drew it, in a CHG column beside the driver's turnover.

Where the numbers come from

The knee angle comes from a motion-capture study of basketball players doing a lateral shuffle, in which the knee was bent 26.8° to 27.1° as the foot touched down (Sensors, 2024). The replay uses 27° for every player, since the simulation holds no stance of each player's own to draw from. The driver's 12° lean and where the arms go are drawing choices, judged by looking at them.

The pose is a set of joint angles applied to the figure the replay already draws:

export function stance(rig, kind) {
  const k = rig.stance_knee_deg * RAD, lean = kind === "drive" ? rig.drive_lean_deg * RAD : 0;
  const out = { pelvis: -lean };
  for (const s of ["l", "r"]) {
    Object.assign(out, { [`${s}_hip`]: k / 2 + lean, [`${s}_knee`]: -k, [`${s}_ankle`]: k / 2 });
  }
  return out;
}

Bending the knee by k while tipping the hip and the ankle by half of k each keeps the feet flat and the pelvis where the simulation put it. Tests check that a pose never appears on a play the simulation did not record as met.