simvx.core.math.types

Lightweight math types – Vec2, Vec3, Quat.

Vec2/Vec3 subclass np.ndarray for zero-copy interop with NumPy and GPU pipelines: v = Vec2(1, 2) np.dot(v, v) # works – it IS a numpy array v.normalized() # returns Vec2, not ndarray

Quat uses slots for memory efficiency (different semantics than vectors). All user-facing angles are in degrees.

Module Contents

Classes

Vec2

2D vector (np.ndarray subclass, shape (2,), float32).

Vec3

3D vector (np.ndarray subclass, shape (3,), float32).

Quat

Quaternion (w, x, y, z) – identity by default.

Curve2D

2D curve with cubic Bezier interpolation.

Curve3D

3D curve with cubic Bezier interpolation.

Functions

normalize

Return normalized copy of vector.

length

Return length of vector.

dot

Dot product of two vectors.

cross

Cross product of two Vec3.

mix

Linear interpolation between a and b.

clamp

Clamp a scalar value between lo and hi.

slerp

Spherical linear interpolation between two quaternions.

Data

API

simvx.core.math.types.__all__

[‘Vec2’, ‘Vec3’, ‘Quat’, ‘Curve2D’, ‘Curve3D’, ‘normalize’, ‘length’, ‘dot’, ‘cross’, ‘mix’, ‘clamp’…

class simvx.core.math.types.Vec2(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)

Bases: numpy.ndarray

2D vector (np.ndarray subclass, shape (2,), float32).

Initialization

__new__(x=0.0, y=None)
__array_finalize__(obj)
__array_ufunc__(ufunc, method, *inputs, **kwargs)
property x: float
property y: float
__eq__(other)
__ne__(other)
__hash__()
__repr__()
__mod__(other)
__bool__()
length() float

Return the magnitude of this vector.

length_squared() float

Return the squared magnitude (avoids sqrt).

normalized() simvx.core.math.types.Vec2

Return a unit-length copy, or zero vector if length is near zero.

dot(other) float

Return the dot product with another vector.

distance_to(other) float

Return the distance to another vector.

direction_to(other) simvx.core.math.types.Vec2

Return the normalized direction toward another vector.

angle_to(other) float

Return the angle between this vector and other (radians).

move_toward(target, delta: float) simvx.core.math.types.Vec2

Move toward target by at most delta distance.

lerp(other, t: float) simvx.core.math.types.Vec2

Linear interpolation between self and other.

snapped(step: float) simvx.core.math.types.Vec2

Round each component to the nearest multiple of step.

rotated(angle_deg: float) simvx.core.math.types.Vec2

Return this vector rotated by angle (degrees).

angle() float

Return the angle of this vector in radians (atan2(y, x)).

reflect(normal) simvx.core.math.types.Vec2

Return this vector reflected off a surface with the given normal.

bounce(normal) simvx.core.math.types.Vec2

Return the bounce vector (negated reflect).

slide(normal) simvx.core.math.types.Vec2

Return this vector slid along a plane defined by normal.

abs() simvx.core.math.types.Vec2

Return vector with absolute values of each component.

cross(other) float

Return the 2D cross product (scalar z-component).

__abs__()
__add__(value)
__and__(value)
__array__(dtype=None)
__array_wrap__(obj)
__contains__(key)
__copy__()
__deepcopy__(memo)
__divmod__(value)
__float__()
__floordiv__()
__ge__(value)
__getitem__(key)
__gt__(value)
__iadd__(value)
__iand__(value)
__ifloordiv__(value)
__ilshift__(value)
__imod__(value)
__imul__(value)
__int__()
__invert__()
__ior__(value)
__ipow__(value)
__irshift__(value)
__isub__(value)
__itruediv__(value)
__ixor__(value)
__le__(value)
__len__()
__lshift__(value)
__lt__(value)
__matmul__(value)
__mul__(value)
__neg__()
__or__(value)
__pos__()
__pow__()
__rshift__()
__setitem__(key, value)
__str__()
__sub__(value)
__truediv__(value)
__xor__(value)
all(axis=None, out=None, keepdims=False)
any(axis=None, out=None, keepdims=False)
argmax(axis=None, out=None)
argmin(axis=None, out=None)
argpartition(kth, axis=-1, kind='introselect', order=None)
argsort(axis=-1, kind='quicksort', order=None)
astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
byteswap(inplace=False)
choose(choices, out=None, mode='raise')
clip(min=None, max=None, out=None)
compress(condition, axis=None, out=None)
conj()
conjugate()
copy(order='C')
cumprod(axis=None, dtype=None, out=None)
cumsum(axis=None, dtype=None, out=None)
diagonal(offset=0, axis1=0, axis2=1)
dump(file)
dumps()
fill(value)
flatten(order='C')
getfield(dtype, offset=0)
item(*args)
itemset(*args)
max(axis=None, out=None)
mean(axis=None, dtype=None, out=None, keepdims=False)
min(axis=None, out=None, keepdims=False)
newbyteorder(new_order='S')
nonzero()
partition(kth, axis=-1, kind='introselect', order=None)
prod(axis=None, dtype=None, out=None, keepdims=False)
ptp(axis=None, out=None)
put(indices, values, mode='raise')
ravel(order='C')
repeat(repeats, axis=None)
reshape(shape, order='C')
resize(new_shape, refcheck=True)
round(decimals=0, out=None)
searchsorted(v, side='left', sorter=None)
setfield(val, dtype, offset=0)
setflags(write=None, align=None, uic=None)
sort(axis=-1, kind='quicksort', order=None)
squeeze(axis=None)
std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
sum(axis=None, dtype=None, out=None, keepdims=False)
swapaxes(axis1, axis2)
take(indices, axis=None, out=None, mode='raise')
tobytes(order='C')
tofile(fid, sep='', format='%s')
tolist()
tostring(order='C')
trace(offset=0, axis1=0, axis2=1, dtype=None, out=None)
transpose(*axes)
var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
view(dtype=None, type=None)
classmethod __class_getitem__(value)
simvx.core.math.types.builtins_abs

None

class simvx.core.math.types.Vec3(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)

Bases: numpy.ndarray

3D vector (np.ndarray subclass, shape (3,), float32).

Initialization

__new__(x=0.0, y=None, z=None)
__array_finalize__(obj)
__array_ufunc__(ufunc, method, *inputs, **kwargs)
property x: float
property y: float
property z: float
__eq__(other)
__ne__(other)
__hash__()
__repr__()
__mod__(other)
__bool__()
length() float

Return the magnitude of this vector.

length_squared() float

Return the squared magnitude (avoids sqrt).

normalized() simvx.core.math.types.Vec3

Return a unit-length copy, or zero vector if length is near zero.

dot(other) float

Return the dot product with another vector.

cross(other) simvx.core.math.types.Vec3

Return the cross product with another vector.

distance_to(other) float

Return the distance to another vector.

direction_to(other) simvx.core.math.types.Vec3

Return the normalized direction toward another vector.

angle_to(other) float

Return the angle between this vector and other (radians).

move_toward(target, delta: float) simvx.core.math.types.Vec3

Move toward target by at most delta distance.

lerp(other, t: float) simvx.core.math.types.Vec3

Linear interpolation between self and other.

snapped(step: float) simvx.core.math.types.Vec3

Round each component to the nearest multiple of step.

__abs__()
__add__(value)
__and__(value)
__array__(dtype=None)
__array_wrap__(obj)
__contains__(key)
__copy__()
__deepcopy__(memo)
__divmod__(value)
__float__()
__floordiv__()
__ge__(value)
__getitem__(key)
__gt__(value)
__iadd__(value)
__iand__(value)
__ifloordiv__(value)
__ilshift__(value)
__imod__(value)
__imul__(value)
__int__()
__invert__()
__ior__(value)
__ipow__(value)
__irshift__(value)
__isub__(value)
__itruediv__(value)
__ixor__(value)
__le__(value)
__len__()
__lshift__(value)
__lt__(value)
__matmul__(value)
__mul__(value)
__neg__()
__or__(value)
__pos__()
__pow__()
__rshift__()
__setitem__(key, value)
__str__()
__sub__(value)
__truediv__(value)
__xor__(value)
all(axis=None, out=None, keepdims=False)
any(axis=None, out=None, keepdims=False)
argmax(axis=None, out=None)
argmin(axis=None, out=None)
argpartition(kth, axis=-1, kind='introselect', order=None)
argsort(axis=-1, kind='quicksort', order=None)
astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
byteswap(inplace=False)
choose(choices, out=None, mode='raise')
clip(min=None, max=None, out=None)
compress(condition, axis=None, out=None)
conj()
conjugate()
copy(order='C')
cumprod(axis=None, dtype=None, out=None)
cumsum(axis=None, dtype=None, out=None)
diagonal(offset=0, axis1=0, axis2=1)
dump(file)
dumps()
fill(value)
flatten(order='C')
getfield(dtype, offset=0)
item(*args)
itemset(*args)
max(axis=None, out=None)
mean(axis=None, dtype=None, out=None, keepdims=False)
min(axis=None, out=None, keepdims=False)
newbyteorder(new_order='S')
nonzero()
partition(kth, axis=-1, kind='introselect', order=None)
prod(axis=None, dtype=None, out=None, keepdims=False)
ptp(axis=None, out=None)
put(indices, values, mode='raise')
ravel(order='C')
repeat(repeats, axis=None)
reshape(shape, order='C')
resize(new_shape, refcheck=True)
round(decimals=0, out=None)
searchsorted(v, side='left', sorter=None)
setfield(val, dtype, offset=0)
setflags(write=None, align=None, uic=None)
sort(axis=-1, kind='quicksort', order=None)
squeeze(axis=None)
std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
sum(axis=None, dtype=None, out=None, keepdims=False)
swapaxes(axis1, axis2)
take(indices, axis=None, out=None, mode='raise')
tobytes(order='C')
tofile(fid, sep='', format='%s')
tolist()
tostring(order='C')
trace(offset=0, axis1=0, axis2=1, dtype=None, out=None)
transpose(*axes)
var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
view(dtype=None, type=None)
classmethod __class_getitem__(value)
class simvx.core.math.types.Quat(w=1.0, x=0.0, y=0.0, z=0.0)

Quaternion (w, x, y, z) – identity by default.

Rotation convention: ZYX intrinsic (yaw-pitch-roll). All angle inputs/outputs in degrees.

Initialization

__slots__

(‘w’, ‘x’, ‘y’, ‘z’)

classmethod from_euler(pitch_deg: float = 0.0, yaw_deg: float = 0.0, roll_deg: float = 0.0) simvx.core.math.types.Quat

Create quaternion from Euler angles in degrees (ZYX intrinsic order).

Args: pitch_deg: Rotation around X axis (degrees) yaw_deg: Rotation around Y axis (degrees) roll_deg: Rotation around Z axis (degrees)

classmethod from_axis_angle(axis: simvx.core.math.types.Vec3 | tuple, degrees: float) simvx.core.math.types.Quat

Create quaternion from axis-angle rotation.

Args: axis: Rotation axis (will be normalized) degrees: Rotation angle in degrees

classmethod look_at(direction: simvx.core.math.types.Vec3 | tuple, up: simvx.core.math.types.Vec3 | tuple = None) simvx.core.math.types.Quat

Create quaternion looking in given direction (right-handed).

Args: direction: Forward direction (will be normalized) up: Up vector (default: Y-up)

inverse() simvx.core.math.types.Quat

Return conjugate (inverse for unit quaternion).

euler_angles() simvx.core.math.types.Vec3

Convert to Euler angles (pitch, yaw, roll) in degrees.

slerp(other: simvx.core.math.types.Quat, t: float) simvx.core.math.types.Quat

Spherical linear interpolation between self and other.

rotate(axis: simvx.core.math.types.Vec3 | tuple, degrees: float) simvx.core.math.types.Quat

Apply additional rotation around axis (degrees).

to_mat4() numpy.ndarray

Convert to 4x4 rotation matrix (numpy, row-major).

__mul__(other)

Hamilton product (Quat * Quat) or rotate vector (Quat * Vec3).

__eq__(other)
__repr__()
__hash__()
__iter__()
class simvx.core.math.types.Curve2D(bake_interval: float = 5.0)

2D curve with cubic Bezier interpolation.

Each point has an optional in-handle and out-handle for smooth curves. Handles are relative offsets from the point position.

Initialization

__slots__

(‘_points’, ‘_baked_points’, ‘_baked_length’, ‘_bake_dirty’, ‘_bake_interval’)

property point_count: int
add_point(position: simvx.core.math.types.Vec2 | tuple, handle_in: simvx.core.math.types.Vec2 | tuple = None, handle_out: simvx.core.math.types.Vec2 | tuple = None, index: int = -1)

Add a point to the curve. Handles are relative offsets from position.

remove_point(index: int)

Remove a point by index.

get_point_position(index: int) simvx.core.math.types.Vec2
set_point_position(index: int, position: simvx.core.math.types.Vec2 | tuple)
get_point_in(index: int) simvx.core.math.types.Vec2
get_point_out(index: int) simvx.core.math.types.Vec2
sample(t: float) simvx.core.math.types.Vec2

Sample the curve at parameter t (0.0 to 1.0). Returns position via cubic Bezier.

sample_baked(offset: float) simvx.core.math.types.Vec2

Sample by distance along the baked curve (0 to baked_length).

sample_baked_with_rotation(offset: float) tuple[simvx.core.math.types.Vec2, float]

Sample position and rotation angle (radians) at distance along curve.

get_baked_length() float

Total arc length of the baked curve.

get_baked_points() list[simvx.core.math.types.Vec2]

Return list of baked (pre-tessellated) points.

clear()

Remove all points.

class simvx.core.math.types.Curve3D(bake_interval: float = 0.2)

3D curve with cubic Bezier interpolation.

Each point has an optional in-handle and out-handle for smooth curves. Handles are relative offsets from the point position.

Initialization

__slots__

(‘_points’, ‘_baked_points’, ‘_baked_length’, ‘_bake_dirty’, ‘_bake_interval’, ‘_tilts’)

property point_count: int
add_point(position: simvx.core.math.types.Vec3 | tuple, handle_in: simvx.core.math.types.Vec3 | tuple = None, handle_out: simvx.core.math.types.Vec3 | tuple = None, index: int = -1, tilt: float = 0.0)

Add a point to the curve. Handles are relative offsets from position.

remove_point(index: int)

Remove a point by index.

get_point_position(index: int) simvx.core.math.types.Vec3
set_point_position(index: int, position: simvx.core.math.types.Vec3 | tuple)
get_point_in(index: int) simvx.core.math.types.Vec3
get_point_out(index: int) simvx.core.math.types.Vec3
get_point_tilt(index: int) float
set_point_tilt(index: int, tilt: float)
sample(t: float) simvx.core.math.types.Vec3

Sample the curve at parameter t (0.0 to 1.0). Returns position via cubic Bezier.

sample_baked(offset: float) simvx.core.math.types.Vec3

Sample by distance along the baked curve (0 to baked_length).

sample_baked_with_rotation(offset: float, up: simvx.core.math.types.Vec3 = None) tuple[simvx.core.math.types.Vec3, simvx.core.math.types.Vec3]

Sample position and forward direction at distance along curve.

Returns (position, forward_direction) where forward is a unit Vec3.

get_baked_length() float
get_baked_points() list[simvx.core.math.types.Vec3]
clear()

Remove all points.

simvx.core.math.types.normalize(v: simvx.core.math.types.Vec2 | simvx.core.math.types.Vec3) simvx.core.math.types.Vec2 | simvx.core.math.types.Vec3

Return normalized copy of vector.

simvx.core.math.types.length(v: simvx.core.math.types.Vec2 | simvx.core.math.types.Vec3) float

Return length of vector.

simvx.core.math.types.dot(a: simvx.core.math.types.Vec2 | simvx.core.math.types.Vec3, b: simvx.core.math.types.Vec2 | simvx.core.math.types.Vec3) float

Dot product of two vectors.

simvx.core.math.types.cross(a: simvx.core.math.types.Vec3, b: simvx.core.math.types.Vec3) simvx.core.math.types.Vec3

Cross product of two Vec3.

simvx.core.math.types.mix(a, b, t: float)

Linear interpolation between a and b.

Works with scalars, Vec2, Vec3, and Quat (uses slerp for Quat).

simvx.core.math.types.clamp(v: float, lo: float, hi: float) float

Clamp a scalar value between lo and hi.

simvx.core.math.types.slerp(a: simvx.core.math.types.Quat, b: simvx.core.math.types.Quat, t: float) simvx.core.math.types.Quat

Spherical linear interpolation between two quaternions.