Pivot Anchor State
Keeps a captured geographic anchor fixed under its original screen pixel while lookAt's range and/or heading change. Per-frame apply solves for lookAt.position via
L_new = A + s · Rotate(L_begin − A, axis = up_A, angle = −(H_new − H_begin)), s = R_new / R_beginContent copied to clipboard
Pure zoom → identity rotation; pure rotation → s = 1. Sharing one instance across pinch / rotate / wheel handlers means simultaneous gestures compose into one self-consistent transform instead of fighting two separate anchors.
Sign of the rotation: heading is clockwise-from-north (right-hand rule axis = −up), so an increase in heading is a negative rotation around +up. Verified on the tangent-plane case L_begin=(0,0), A=(E,0), Δh=+90° → L_new=(E,−E).