Running track
An eight-lane track from above. The 200 m in lane four is lit from its staggered start to the finish.
Made with Claude Opus 5.5
- Technique
- technical drawing
- Shape
- Any screen
- Added
- 27 September 2026
Colours
- #1C1B1Abackground
- #DAD8CEforeground
- #CF6A4Caccent
Export
FormatThis browser can’t make WebP files.
Shapecropped from 16:9
Crop
SizeThis browser can’t draw a file that large.
Notes
Drawn to the measurements of the standard 400 m track: bends of 36.5 m radius, 84.39 m straights and 1.22 m lanes. A 200 m race covers half a bend and the home straight, so each lane starts further round to make up for its longer curve, measured 0.2 m out from the lane’s inner line (0.3 m from the kerb in lane one).
Sources
- IAAF, IAAF Track and Field Facilities Manual, chapters 1-3, 2008.
- IAAF, IAAF 400 metre standard track, marking plan, 2008.
Source code
wallpapers/running-track/design.py, 64 lines
"""A 400 m athletics track in plan, drawn to scale and cropped past one bend: the 200 m staggered starts, and lane 4's race picked out to the finish."""
import math
from itertools import pairwise
from walldye import ACCENT, ACCENT_1, ACCENT_3, UI, UI_ALT, Canvas, P, Vec, design, polar
from walldye.geom import Affine
SC = 10 # px per metre
A = 84.39 / 2 * SC # half the straight
R0, LANE, N = 36.5, 1.22, 8 # kerb radius and lane width (m), lanes
LEG = 4 # the lane picked out
FINISH_INSET = 158 # finish line to the far edge; the bend beyond it runs off the canvas
# Local frame: origin at the track's centre, +x along the home straight towards the finish,
# +y towards the home straight; angles in degrees about the start bend, clockwise on screen.
BEND = Vec(-A, 0)
BEND_START, BEND_END = -90, -270 # the bend is run anticlockwise, infield on the left
def run_r(n: int) -> float:
"""Measured running-line radius (m) of lane n: 0.30 m off the kerb in lane 1, 0.20 m off the line otherwise."""
return R0 + (n - 1) * LANE + (0.30 if n == 1 else 0.20)
def start_deg(n: int) -> float:
"""Where lane n's 200 m start sits on the bend: each lane runs the rest of the bend plus the
straight, so the outer lanes start further round."""
return BEND_START - math.degrees(math.pi * (run_r(n) - run_r(1)) / run_r(n))
@design(aspects="any")
def draw(s: Canvas) -> None:
# The finish line sits FINISH_INSET short of the right edge on a landscape screen. On a
# portrait one the plan turns a quarter clockwise, which keeps the running direction, so
# the start bend is at the top and the finish near the bottom edge.
reach = A + FINISH_INSET
if s.landscape:
place = Affine.frame((s.w - reach, s.h / 2), deg=0)
else:
place = Affine.frame((s.w / 2, s.h - reach), deg=90)
r_out = (R0 + N * LANE) * SC
with s.group(transform=place):
lines = P()
for k in range(N + 1):
r = (R0 + k * LANE) * SC
lines.rrect(-A - r, -r, 2 * (A + r), 2 * r, r)
s.stroke(lines, UI, 1.5)
# the staggered starts, then the common finish line across every lane
marks = P()
for n in range(1, N + 1):
a = start_deg(n)
marks.M(polar(BEND, (R0 + (n - 1) * LANE) * SC, deg=a))
marks.L(polar(BEND, (R0 + n * LANE) * SC, deg=a))
marks.M(A, R0 * SC).V(r_out)
s.stroke(marks, UI_ALT, 2)
# The race eases in through two darker steps over the first fifth of the bend.
rc = (R0 + (LEG - 0.5) * LANE) * SC
a0 = start_deg(LEG)
cuts = [a0 + f * (BEND_END - a0) for f in (0, 0.1, 0.2)]
for (a, b), tone in zip(pairwise(cuts), (ACCENT_3, ACCENT_1), strict=True):
s.stroke(P().arc(BEND, rc, deg=(a, b)), tone, 3)
s.stroke(P().arc(BEND, rc, deg=(cuts[-1], BEND_END)).H(A), ACCENT, 3)"""A 400 m athletics track in plan, drawn to scale and cropped past one bend: the 200 m staggered starts, and lane 4's race picked out to the finish."""
import math
from itertools import pairwise
from walldye import ACCENT, ACCENT_1, ACCENT_3, UI, UI_ALT, Canvas, P, Vec, design, polar
from walldye.geom import Affine
SC = 10 # px per metre
A = 84.39 / 2 * SC # half the straight
R0, LANE, N = 36.5, 1.22, 8 # kerb radius and lane width (m), lanes
LEG = 4 # the lane picked out
FINISH_INSET = 158 # finish line to the far edge; the bend beyond it runs off the canvas
# Local frame: origin at the track's centre, +x along the home straight towards the finish,
# +y towards the home straight; angles in degrees about the start bend, clockwise on screen.
BEND = Vec(-A, 0)
BEND_START, BEND_END = -90, -270 # the bend is run anticlockwise, infield on the left
def run_r(n: int) -> float:
"""Measured running-line radius (m) of lane n: 0.30 m off the kerb in lane 1, 0.20 m off the line otherwise."""
return R0 + (n - 1) * LANE + (0.30 if n == 1 else 0.20)
def start_deg(n: int) -> float:
"""Where lane n's 200 m start sits on the bend: each lane runs the rest of the bend plus the
straight, so the outer lanes start further round."""
return BEND_START - math.degrees(math.pi * (run_r(n) - run_r(1)) / run_r(n))
@design(aspects="any")
def draw(s: Canvas) -> None:
# The finish line sits FINISH_INSET short of the right edge on a landscape screen. On a
# portrait one the plan turns a quarter clockwise, which keeps the running direction, so
# the start bend is at the top and the finish near the bottom edge.
reach = A + FINISH_INSET
if s.landscape:
place = Affine.frame((s.w - reach, s.h / 2), deg=0)
else:
place = Affine.frame((s.w / 2, s.h - reach), deg=90)
r_out = (R0 + N * LANE) * SC
with s.group(transform=place):
lines = P()
for k in range(N + 1):
r = (R0 + k * LANE) * SC
lines.rrect(-A - r, -r, 2 * (A + r), 2 * r, r)
s.stroke(lines, UI, 1.5)
# the staggered starts, then the common finish line across every lane
marks = P()
for n in range(1, N + 1):
a = start_deg(n)
marks.M(polar(BEND, (R0 + (n - 1) * LANE) * SC, deg=a))
marks.L(polar(BEND, (R0 + n * LANE) * SC, deg=a))
marks.M(A, R0 * SC).V(r_out)
s.stroke(marks, UI_ALT, 2)
# The race eases in through two darker steps over the first fifth of the bend.
rc = (R0 + (LEG - 0.5) * LANE) * SC
a0 = start_deg(LEG)
cuts = [a0 + f * (BEND_END - a0) for f in (0, 0.1, 0.2)]
for (a, b), tone in zip(pairwise(cuts), (ACCENT_3, ACCENT_1), strict=True):
s.stroke(P().arc(BEND, rc, deg=(a, b)), tone, 3)
s.stroke(P().arc(BEND, rc, deg=(cuts[-1], BEND_END)).H(A), ACCENT, 3)
Run it yourself
$ git clone https://github.com/nickolaj-jepsen/walldye && cd walldye$ uv run walldye render running-track --theme fireproof -o running-track-fireproof-16x9.svg