From 2169dc25eafc4a516bb61d60331ac15f0556f52d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Fri, 24 Apr 2026 18:54:54 -0700 Subject: [PATCH 1/2] Add additional math methods. --- crates/processing_pyo3/mewnala/__init__.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/crates/processing_pyo3/mewnala/__init__.py b/crates/processing_pyo3/mewnala/__init__.py index 4427ced..5f4f10c 100644 --- a/crates/processing_pyo3/mewnala/__init__.py +++ b/crates/processing_pyo3/mewnala/__init__.py @@ -1,17 +1,17 @@ from .mewnala import * -# re-export the native submodules as submodules of this module, if they exist -# this allows users to import from `mewnala.math` and `mewnala.color` -# if they exist, without needing to know about the internal structure of the native module import sys as _sys from . import mewnala as _native -for _name in ("math", "color"): - _sub = getattr(_native, _name, None) - if _sub is not None: - _sys.modules[f"{__name__}.{_name}"] = _sub + +_color = getattr(_native, "color", None) +if _color is not None: + _sys.modules[f"{__name__}.color"] = _color + +from . import math # noqa: E402 (Python submodule, extends native math) +from .math import * # noqa: E402,F401,F403 # global var handling. for wildcard import of our module, we copy into globals, otherwise -# we dispatch to get attr and call the underlying getter method +# we dispatch to get attr and call the underlying getter method _DYNAMIC_GRAPHICS_ATTRS = ( "width", @@ -69,6 +69,3 @@ def __getattr__(name): def __dir__(): return sorted(set(list(globals().keys()) + list(_DYNAMIC))) - - -del _sys, _name, _sub From d2a319de357580e4650d2932b1085fa2a90f32c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?charlotte=20=F0=9F=8C=B8?= Date: Fri, 24 Apr 2026 18:56:12 -0700 Subject: [PATCH 2/2] Add additional math methods. --- crates/processing_pyo3/mewnala/math.py | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 crates/processing_pyo3/mewnala/math.py diff --git a/crates/processing_pyo3/mewnala/math.py b/crates/processing_pyo3/mewnala/math.py new file mode 100644 index 0000000..9fe4881 --- /dev/null +++ b/crates/processing_pyo3/mewnala/math.py @@ -0,0 +1,69 @@ +"""Processing math methods and vector/quaternion types.""" +from .mewnala import math as _native_math +from math import ( + sin, cos, tan, + asin, acos, atan, atan2, + sqrt, exp, log, + ceil, floor, + degrees, radians, +) + +Vec2 = _native_math.Vec2 +Vec3 = _native_math.Vec3 +Vec4 = _native_math.Vec4 +Quat = _native_math.Quat +VecIter = _native_math.PyVecIter +vec2 = _native_math.vec2 +vec3 = _native_math.vec3 +vec4 = _native_math.vec4 +quat = _native_math.quat + + +def sq(x): + return x * x + + +def pow(base, exponent): + return base ** exponent + + +def constrain(value, low, high): + if value < low: + return low + if value > high: + return high + return value + + +def lerp(start, stop, amt): + return start + (stop - start) * amt + + +def norm(value, start, stop): + return (value - start) / (stop - start) + + +def remap(value, start1, stop1, start2, stop2): + return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)) + + +def mag(*args): + if len(args) == 2: + a, b = args + return sqrt(a * a + b * b) + if len(args) == 3: + a, b, c = args + return sqrt(a * a + b * b + c * c) + raise TypeError(f"mag() takes 2 or 3 arguments ({len(args)} given)") + + +def dist(*args): + if len(args) == 4: + x1, y1, x2, y2 = args + dx, dy = x2 - x1, y2 - y1 + return sqrt(dx * dx + dy * dy) + if len(args) == 6: + x1, y1, z1, x2, y2, z2 = args + dx, dy, dz = x2 - x1, y2 - y1, z2 - z1 + return sqrt(dx * dx + dy * dy + dz * dz) + raise TypeError(f"dist() takes 4 or 6 arguments ({len(args)} given)")