Skip to content

Pinning a HUD to a Moving Camera

 2 min A label pinned to the viewport exposes the difference between world, camera, and screen coordinates.
Published

Oct 22, 2009

In the VPython version I was using, the scene objects I could create lived in world coordinates. The spheres had positions, the arrows had axes, and the camera moved around all of it. A HUD—a label pinned to the corner of the view, a readout that stays put while the scene spins—wants exactly the opposite: a position fixed relative to the view, indifferent to the world.

I asked the VPython list for that as a primitive: a way to attach text or labels to the viewport rather than to world space.

There are three coordinate frames in play. World space, where the scene lives. Camera space, defined by where the eye sits and which way it looks. Screen space, the 2D projection the user finally sees. “Pinned to the corner” means fixed relative to the screen. Attaching a label to the camera handles camera movement, but changes to the projection or viewport can still move its screen position. Reconstructing that corner in world space means tracking both.

A scene graph that only stores world coordinates can still fake a HUD, but the workaround shows what is missing. In the thread’s follow-up, I described the one in my own log visualizer: move a dedicated viewport frame and rescale its objects as the camera moves, or make the global frame the overlay. The label is camera-space state being smuggled through a world-space slot.

A viewport overlay stores that state in the frame where it is constant. That removes camera-change bookkeeping from the application; it does not make rendering free. The renderer still transforms, lays out, and draws the overlay each frame. I floated a pin method as the VPython primitive.

The same thread carried a second request with the same root: graph output and the 3D scene composed into one window, rather than two unrelated windows—while accounting for their different scale systems. A plot’s axes and a scene’s world units are, again, different coordinate frames, and composing them is frame management.

The VPython Years follows the other questions that grew out of trying to use the library.