Matrices & Coordinate Frames¶
pytanga.geometry provides two small, algebra-free primitives for expressing
numeric transforms and axis conventions: Matrix and CoordinateFrame. They
back the camera-calibration helpers and can be passed straight to the scene
graph's set_transform() / apply_transform().
Matrix¶
Matrix is a thin, typed wrapper around a square numpy array (3×3 or 4×4),
using the column-vector convention (v' = M @ v).
import math
from pytanga.geometry import Direction, Matrix, Point
# Rotation about +x by 90° (Rodrigues).
r = Matrix.rotation((1.0, 0.0, 0.0), math.pi / 2)
# Composition, transpose, inverse, determinant.
r @ r.T == Matrix.identity(3)
r.inverse() @ r == Matrix.identity(3)
r.det() # ≈ 1.0
r.is_rotation() # True
# Apply to points/directions (homogeneous for a 4×4 matrix).
r @ Point(0.0, 1.0, 0.0) # → Point(0.0, 0.0, 1.0)
r @ Direction(0.0, 1.0, 0.0) # → Direction(0.0, 0.0, 1.0)
# Constructors.
Matrix.translation(1.0, 2.0, 3.0) # 4×4 homogeneous
Matrix.scale(0.5) # 3×3 uniform
Matrix.from_axes(x, y, z) # 3×3 change-of-basis (columns = axes)
Matrix.from_R_t(R, t) # 4×4 rigid transform [R t; 0 1]
| Member | Description |
|---|---|
to_matrix() / to_numpy() |
the raw numpy array |
T, inverse(), det() |
linear algebra |
is_rotation() |
orthonormal with determinant ≈ +1 |
@ |
compose matrices, or transform a Point/Direction |
identity(n) / translation(…) / rotation(axis, angle) / scale(…) / from_axes(x, y, z) / from_R_t(R, t) |
constructors |
MatrixProvider¶
Anything with a to_matrix() -> np.ndarray method satisfies the
MatrixProvider protocol. Matrix, CoordinateFrame, and Transform all do,
so any of them can be used wherever a 4×4 matrix is expected — including
set_transform() / apply_transform():
from pytanga.geometry import MatrixProvider, OpenCVFrame
from pytanga.viz import Visualizer
assert isinstance(OpenCVFrame(), MatrixProvider)
group = viz.add_group("data")
group.set_transform(OpenCVFrame()) # remap OpenCV-frame children into the world
CoordinateFrame¶
CoordinateFrame(x, y, z) names where a child frame's +x/+y/+z axes point
in the parent (right-handed) frame. to_matrix() returns the 4×4
change-of-basis matrix (a proper rotation), and handedness() reports +1
(right-handed) or -1 (left-handed).
from pytanga.geometry import CoordinateFrame, Direction
# The standard frame (identity).
CoordinateFrame(
x=Direction(1.0, 0.0, 0.0),
y=Direction(0.0, 1.0, 0.0),
z=Direction(0.0, 0.0, 1.0),
)
OpenCVFrame¶
OpenCVFrame() is a ready-made frame for the OpenCV camera convention
(x right, y down, z forward). It is a 180° rotation about +x relative to the
standard x-right / y-up / z-toward-viewer frame — a proper rotation
(determinant +1), so it keeps the world right-handed and composes with other
rotations.
from pytanga.geometry import OpenCVFrame
frame = OpenCVFrame()
frame.handedness() # 1
frame.to_matrix() # diag([1, -1, -1, 1])
Use it to remap OpenCV-frame data into the right-handed world — either by
passing it to set_transform(), or through CameraCalibration (see
Camera Calibration).