Programmatic Ground Marks
Forensics, parking lot · test run 2026-10-14 · B1 tire marks and B2 glass drawn in code over the accepted plates
- Q1: Your read of these composites at phone size against a painted mark +8
- A side-by-side with one painted tire-mark layer, once one exists +5
- The same renderer in Swift (Core Image or Metal) matching these frames on device +6
- Q2: A decision on upright props (ladders, crates, dumpsters) +3
Open Questions (1 open, 1 answered)
Q1 answered by Sarah, 2026-10-14: yes. Ground marks are drawn by the app. Glass gets two types: tempered cubes and plate-glass shards. Textures are requested in docs/spec/forensics/requests/2026-10-14-ground-textures-1.md.
Recommendation: yes. These composites read as rubber and glass at phone size, sit on their calibrated spots exactly, and cost nothing per new size, curve or position. The painted path costs eight registered paintings for two cases, and a repaint for every geometry change. The cost of switching is the renderer in Swift and one overhead texture per mark type.
Recommendation: decide after Q1 lands. Keep the alley's accepted painted layers. For new scenes, test 3D models rendered with the calibrated camera before committing either way, since a flat image of a standing object holds only from one viewpoint.
What was tested
Two overhead textures were generated in code: a straight rubber strip (12 m × 0.25 m) and a glass scatter (0.6 × 0.4 m). For each output pixel, the renderer traces back to the ground point under it through the plate's calibrated camera, finds that point's position along and across each mark, and reads the texture there. The strip bends to any arc this way. Rubber darkens the plate beneath it, so the plate's own light carries through; glass takes the plate's local brightness. The script is docs/reviews/2026-10-14-programmatic-ground-marks/render.py, and all six renders take 14 seconds in plain Python.
The marks use the same calibrated cameras as the checker. Each render's search box, which is deliberately padded a few pixels beyond the marks, encloses the checker's own projection of the same geometry and runs 0–14 px wider than it.
B1 tire marks
B2 glass
Plate-glass shards (added after Q1)
Larger, irregular pieces as from a broken shop or house window, 1.5 to 12 cm, mostly clear, with green edges and a few bright edges catching the light. Rendered at B2-001's spot for comparison with the tempered cubes.
Textures
Findings
- Tire marks hold up. Streaking, soft ends and the plate's lighting read as rubber on lit asphalt in both views. Foreshortening comes from the camera, so the far ends thin correctly.
- Glass reads, but less richly than paint. At phone size it is a glinting scatter. Up close the cubes are uniform squares; a hand-painted overhead texture would add irregular fragments and real highlights, and drops in without code changes.
- Lighting is borrowed, not simulated. Rubber multiplies the plate, which is physically right. Glass brightens with the plate's local light; strong directional glints would need the scene's lights, which the scene file already lists.
- Ground only. This works because the marks lie on a known plane. It does not extend to standing objects (Q2).
What changes if Q1 is yes
- The props request becomes: paint one overhead texture per mark type (rubber strip, glass scatter), on transparency, at a stated scale. No registration, no per-spot layers.
- The case files keep their geometry; the app draws each mark from it. Any chord, track, offset or spot needs no new art.
- The per-spot blockouts and the arc-layer checks added today stop applying to ground marks. They stay for the alley's painted layers.
- Phase 2's Swift renderer gains a ground-decal pass: the camera projection is already in the plan to port, and the decal step is the inverse mapping shown here.
- Q1: Your read of these composites at phone size against a painted mark +8
- A side-by-side with one painted tire-mark layer, once one exists +5
- The same renderer in Swift (Core Image or Metal) matching these frames on device +6
- Q2: A decision on upright props (ladders, crates, dumpsters) +3