import math
from collections import defaultdict

u, v = 70.0, 60.0
cx, cy, focal = 50.0, 50.0, 100.0
depths = ((8.0, 0.2), (10.0, 0.6), (12.0, 0.2))

def lift(depth, pitch_degrees):
    x = (u-cx)*depth/focal
    y = (v-cy)*depth/focal
    z = depth
    angle = math.radians(pitch_degrees)
    world_z = math.sin(angle)*y + math.cos(angle)*z
    return x, world_z

def splat(cell_width, pitch):
    grid = defaultdict(float)
    for depth, mass in depths:
        x, z = lift(depth, pitch)
        cell = (math.floor(x/cell_width), math.floor(z/cell_width))
        grid[cell] += mass
    assert abs(sum(grid.values())-1.0) < 1e-12
    return [(cell, round(mass, 3)) for cell, mass in sorted(grid.items())]

for width in (1.0, 2.0):
    for pitch in (0.0, 5.0, -5.0):
        print('width', width, 'pitch', pitch, 'cells', splat(width, pitch))
base = lift(10.0, 0.0)
tilted = lift(10.0, 5.0)
print('depth10_forward_shift', round(tilted[1]-base[1], 4))
assert base == (2.0, 10.0)
