Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Precision Handling

Cadastral surveying works in large coordinate systems — a typical UTM Easting/Northing looks like 500,000m / 5,000,000m. Rendering that directly on the GPU is a precision problem: a 32-bit float (f32) at 1,000,000m has roughly 0.125m of representable precision, which is useless for millimeter-accuracy survey work.

The solution: camera-relative rendering in f64

  1. All geometry is stored in f64 world coordinates.

  2. Camera position is tracked in f64 — handles coordinates like 500,000m without loss.

  3. Before rendering, coordinates are transformed to camera-relative space, in f64:

    #![allow(unused)]
    fn main() {
    vertex_camera = vertex_world - camera_position
    }
  4. Only camera-relative coordinates are converted to f32, right before upload to the GPU vertex buffer.

Because camera-relative coordinates are small (bounded by whatever’s actually visible on screen), f32 precision is excellent for them — even though the original world coordinates were far too large for f32 to represent precisely.

Worked example

A point at (500000.001, 5000000.001) with the camera at (500000, 5000000) becomes (0.001, 0.001) in camera-relative space — small enough for f32 to represent exactly.

Rule of thumb

Never apply the camera position transform in a shader. Do the world-to-camera-relative subtraction in f64 on the CPU first, then hand the already-small f32 values to the GPU. Applying it in the shader (in f32) reintroduces the precision loss the whole scheme exists to avoid.

Where this matters in the codebase

  • renderer/mod.rs — the wgpu pipeline that performs the camera-relative transform.
  • renderer/camera.rsCamera2D, tracked in f64.
  • Every geometry type in geometry/ stores its coordinates as f64.