Math Types

SimVX math types are numpy.ndarray subclasses – they interoperate directly with NumPy operations while providing named accessors and convenience methods. No PyGLM dependency.

Vec2

2D vector (ndarray subclass, shape (2,), float32):

from simvx.core import Vec2

v = Vec2(3, 4)
v.length()          # 5.0
v.normalized()      # Vec2(0.6, 0.8)
v.dot(Vec2(1, 0))   # 3.0

# Arithmetic (numpy broadcasting)
a + b, a - b, a * 2, a / 3
Vec2(1)              # Vec2(1, 1) -- scalar broadcast

# NumPy interop
import numpy as np
np.linalg.norm(v)    # 5.0 -- works because Vec2 IS an ndarray

Vec3

3D vector (ndarray subclass, shape (3,), float32):

from simvx.core import Vec3

v = Vec3(1, 2, 3)
v.length()           # 3.742
v.length_squared()   # 14
v.normalized()       # unit vector
v.dot(other)         # dot product
v.cross(other)       # cross product

# Indexing
v[0], v[1], v[2]     # x, y, z
v.x, v.y, v.z        # named access
Vec3(1)               # Vec3(1, 1, 1) -- scalar broadcast

Quat

Unit quaternion for 3D rotations. All angle arguments use radians.

import math
from simvx.core import Quat

# Construction
q = Quat()                                              # identity
q = Quat.from_euler(pitch=math.radians(45), yaw=math.radians(90))
q = Quat.from_axis_angle((0, 1, 0), math.pi / 2)       # axis-angle
q = Quat.look_at((0, 0, -1))                            # look direction

# Operations
q.inverse()                          # conjugate (inverse for unit quaternion)
q.euler_angles()                     # Vec3(pitch, yaw, roll) in radians
q.slerp(other, 0.5)                 # spherical interpolation
q.rotate((0, 1, 0), math.pi / 6)   # compose with additional rotation
q.to_mat4()                          # convert to 4x4 numpy matrix

# Rotate a vector
rotated = q * Vec3(1, 0, 0)

Rotation Convention

All SimVX internal rotation APIs use radians. This applies to:

  • Quat.from_euler(), Quat.from_axis_angle(), Quat.rotate()

  • Node3D.rotate(axis, angle), Node2D.rotate(radians)

  • euler_angles() return values

  • Basis.from_euler(), Basis.from_axis_angle(), Basis.get_euler()

  • Matrix functions: perspective(fov), rotate(axis, angle)

UIs and editor tools auto-convert to degrees for display (inspector converts radians internally).

Matrix Functions

Pure NumPy matrix utilities in simvx.core.math:

from simvx.core import perspective, look_at, translate, rotate, scale, identity

# Projection (fov in radians)
proj = perspective(fov=math.radians(60), aspect=16/9, near=0.1, far=100.0)

# View
view = look_at(eye=(0, 5, 10), center=(0, 0, 0), up=(0, 1, 0))

# Model transforms (angle in radians)
model = translate((1, 2, 3)) @ rotate((0, 1, 0), angle=math.pi/2) @ scale((2, 2, 2))

All matrices are NumPy arrays in row-major order. Vulkan shaders expect column-major, so matrices are transposed at the GPU boundary in the forward renderer.

Edge Case Safety

Matrix functions guard against degenerate inputs that would otherwise produce NaN or infinity:

  • look_at() – When the forward direction is nearly parallel to the up vector (e.g. looking straight up/down), a fallback up vector is chosen automatically to avoid a zero cross product.

  • perspective() – FOV is clamped to 1–179 degrees, aspect ratio floors at a small positive value, and near/far are validated to prevent division by zero.

  • orthographic() – Degenerate bounds (left == right, top == bottom, near == far) are corrected to avoid division by zero.

  • Quat.slerp() – Handles both nearly-identical quaternions (< 0.03 degrees apart) and nearly-opposite quaternions (~180 degrees apart) by falling back to normalised linear interpolation.

Utility Functions

from simvx.core import normalize, length, dot, cross, mix, clamp, slerp

normalize(v)         # unit vector
length(v)            # magnitude
dot(a, b)            # dot product
cross(a, b)          # cross product (Vec3 only)
mix(a, b, 0.5)       # linear interpolation (slerp for Quat)
clamp(x, 0.0, 1.0)  # clamp scalar
slerp(q1, q2, 0.5)  # quaternion slerp

API Reference

See simvx.core.math.types for the complete math API.