spacr.qt.widgets.volume_view

Camera arithmetic for the Gate Editor’s 3D volume.

Pure numpy, no Qt and no matplotlib, so it can be tested on its own.

matplotlib describes a 3D camera with three angles – elev, azim and roll – and builds the screen axes from them in Axes3D.get_proj. Dragging by adding to elev and azim is a turntable: it can never roll the view, it flips when the elevation passes the pole, and a clamp on the elevation (what the editor used to do) makes whole orientations unreachable.

This module goes the other way round. The camera is held as the three screen axes u (right), v (up) and w (out of the screen) in matplotlib’s box coordinates; a drag rotates that frame about the screen axes, which is a trackball, and angles_from_axes() turns the frame back into the three angles view_init takes. Every orientation is reachable and nothing snaps.

Functions

angles_from_axes(→ Angles)

The (elev, azim, roll) that make matplotlib draw this frame.

rotate_about_world(→ Angles)

Turn the volume about one of its own data axes.

trackball(→ Angles)

Turn the view as if the volume were grabbed and dragged.

view_axes(elev, azim[, roll])

The screen axes matplotlib builds from three camera angles.

Module Contents

spacr.qt.widgets.volume_view.angles_from_axes(u, w) → Angles[source]

The (elev, azim, roll) that make matplotlib draw this frame.

elev is kept inside [-90, 90] so the vertical never flips; the roll then carries whatever turn about the line of sight the frame has. Looking straight down (or up) the azimuth is free, so it is chosen to make the roll zero.

Parameters:
  • u – the screen’s right-pointing axis.

  • w – the axis pointing out of the screen.

spacr.qt.widgets.volume_view.rotate_about_world(elev: float, azim: float, roll: float, axis: str, degrees: float) → Angles[source]

Turn the volume about one of its own data axes.

Parameters:
  • elev – the camera elevation in degrees.

  • azim – the camera azimuth in degrees.

  • roll – the camera roll in degrees.

  • axis – "x", "y" or "z" – the measurement the volume spins about, which stays put on screen while the other two turn.

  • degrees – how far; positive turns the volume anticlockwise when that axis points at the viewer.

Returns:

the new (elev, azim, roll).

spacr.qt.widgets.volume_view.trackball(elev: float, azim: float, roll: float, right_degrees: float, up_degrees: float) → Angles[source]

Turn the view as if the volume were grabbed and dragged.

A drag to the right turns the volume about the screen’s vertical so its front follows the pointer; a drag up turns it about the screen’s horizontal. Both are applied to the frame, not to the angles, so the two directions compose freely and there is no pole to stop at.

Parameters:
  • elev – the camera elevation in degrees.

  • azim – the camera azimuth in degrees.

  • roll – the camera roll in degrees.

  • right_degrees – how far the pointer moved right, as an angle.

  • up_degrees – how far it moved up, as an angle.

Returns:

the new (elev, azim, roll).

spacr.qt.widgets.volume_view.view_axes(elev: float, azim: float, roll: float = 0.0)[source]

The screen axes matplotlib builds from three camera angles.

Mirrors Axes3D.get_proj and proj3d._view_axes for a Z-up axes: w points from the centre of the box to the eye, u is V x w with V the vertical axis (negated past the pole), and roll turns u and v about w.

Parameters:
  • elev – the camera elevation in degrees.

  • azim – the camera azimuth in degrees.

  • roll – the camera roll in degrees.

Returns:

(u, v, w), three orthonormal vectors.