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 degrees.
from simvx.core import Quat
# Construction
q = Quat() # identity
q = Quat.from_euler(pitch=45, yaw=90) # degrees
q = Quat.from_axis_angle((0, 1, 0), 90) # axis-angle (degrees)
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 degrees
q.slerp(other, 0.5) # spherical interpolation
q.rotate((0, 1, 0), 30) # compose with additional rotation (degrees)
q.to_mat4() # convert to 4x4 numpy matrix
# Rotate a vector
rotated = q * Vec3(1, 0, 0)
Rotation Convention¶
All SimVX rotation APIs use degrees, not radians. This applies to:
Quat.from_euler(),Quat.from_axis_angle()Node3D.rotate(axis, degrees)euler_angles()return values
Matrix Functions¶
Pure NumPy matrix utilities in simvx.core.math:
from simvx.core import perspective, look_at, translate, rotate, scale, identity
# Projection
proj = perspective(fov_degrees=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
model = translate((1, 2, 3)) @ rotate((0, 1, 0), degrees=90) @ 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.