matthewplotlib

matthewplotlib.data

type number = int | float | numpy.integer | numpy.floating
type ColorSpec = None | ColorLike | ArrayLike
type Series = numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]] | tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], ColorSpec] | tuple[ArrayLike, ArrayLike] | tuple[ArrayLike, ArrayLike, ColorSpec] | axis | tuple[axis, ColorSpec]
type Series3 = numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]] | tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], ColorSpec] | tuple[ArrayLike, ArrayLike, ArrayLike] | tuple[ArrayLike, ArrayLike, ArrayLike, ColorSpec] | axis | tuple[axis, ColorSpec]
def parse_range( data: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], range: tuple[number | None, number | None] | None) -> tuple[number, number]:
def parse_color_spec( cs: ColorSpec, n: int) -> numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]:
def parse_series( series: Series) -> tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]]:
def parse_multiple_series( *seriess: Series) -> tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]]:
def parse_series3( series: Series3) -> tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]]:
def parse_multiple_series3( *seriess: Series3) -> tuple[numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]], numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]]:
@dataclasses.dataclass(frozen=True)
class axis:
axis(a: number = 0.0, b: number = 1.0, n: int = 10)
a: number = 0.0
b: number = 1.0
n: int = 10
xs: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
ys: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
zs: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
class xaxis(axis):

axis(a: 'number' = 0.0, b: 'number' = 1.0, n: 'int' = 10)

xs: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
Inherited Members
axis
axis
a
b
n
ys
zs
class yaxis(axis):

axis(a: 'number' = 0.0, b: 'number' = 1.0, n: 'int' = 10)

ys: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
Inherited Members
axis
axis
a
b
n
xs
zs
class zaxis(axis):

axis(a: 'number' = 0.0, b: 'number' = 1.0, n: 'int' = 10)

zs: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[~_ScalarT]]
Inherited Members
axis
axis
a
b
n
xs
ys
def project3( xyz: numpy.ndarray, camera_position: numpy.ndarray = array([0., 0., 2.]), camera_target: numpy.ndarray = array([0., 0., 0.]), scene_up: numpy.ndarray = array([0., 1., 0.]), fov_degrees: float = 90.0) -> tuple[numpy.ndarray, numpy.ndarray]:

Project a 3d point cloud into two dimensions based on a given camera configuration.

Inputs:

  • xyz: float[n, 3]. The points to project, with columns corresponding to X, Y, and Z.
  • camera_position: float[3] (default: [0. 0. 2.]). The position at which the camera is placed. The default is positioned along the positive Z axis.
  • camera_target: float[3] (default: [0. 0. 0.]). The position towards which the camera is facing. Should be distinct from camera position. The default is that the camera is facing towards the origin.
  • scene_up: float[3] (default: [0. 1. 0.]). The unit vector designating the 'up' direction for the scene. The default is the positive Y direction. Should not have the same direction as camera_target - camera_position.
  • fov_degrees: float (default 90). Field of view. Points within a cone (or frustum) of this angle leaving the camera are projected into the unit disk (or the square [-1,1]^2).

Returns:

  • xy: float[n, 2]. Projected points.
  • valid: bool[n]. Mask indicating which of the points are in front of the camera.

Notes:

  • The combined effect of the defaults is that the camera is looking down the Z axis towards the origin from the positive direction, with the X axis extending towards the right and the Y axis extending upwards, with the field of view ensuring that points within the cube [-1,1]^3 are projected into the square [-1,1]^2.
  • The valid mask only considers whether points are in front of the camera. A more comprehensive frustum clipping approach is not supported.

Internal notes:

  • This implementation uses a coordinate system for the camera where X and Y point left and up respectively and Z points towards the object ahead of the camera (an alternative convention is for Z to point behind the camera).