From 4bfa01f9606a10bb364747bcf288ffa61d62862f Mon Sep 17 00:00:00 2001 From: kk8bit Date: Sun, 20 Sep 2026 21:01:38 +0800 Subject: [PATCH] Add trigonometry and friends to AbcMath The expression evaluator whitelists the callables it will dispatch, so extending it is a matter of adding entries: the trig family, their hyperbolic and inverse forms, radians/degrees conversion, sqrt, exp, the logarithms, floor, ceil, hypot and abs. Constants pi, e and tau resolve the same way a, b and c do. Trigonometry is in radians, as in Python, so sin(radians(a)) is how you feed it degrees. The result guard only caught NaN. log(0) and similar produce infinities that int() then refuses, so infinities are folded to 0 alongside NaN. Closes #12. --- CHANGELOG.md | 2 ++ README.md | 14 ++++++++++---- nodes/abc_math.py | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16cbd80..f984d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [未发布 Unreleased] +- 数学表达式计算节点支持三角函数、对数指数和常量(`sin`/`cos`/`tan`/`atan2`/`sqrt`/`log`/`exp`/`pi`/`e` 等),三角函数以弧度为单位,可用 `radians()` 转换 +- AbcMath now supports trigonometric, logarithmic and exponential functions plus constants (`sin`, `cos`, `tan`, `atan2`, `sqrt`, `log`, `exp`, `pi`, `e`, …); trigonometry works in radians, convert with `radians()` - 批量图片载入节点新增 `filenames` 输出(原文件名),配合自定义图像保存节点新增的 `exact_filename` 开关,即可按原文件名保存批处理结果 - Load Image Folder gained a `filenames` output, and Custom Save Image an `exact_filename` toggle, so batch results can be saved under their original names diff --git a/README.md b/README.md index 6192093..b8a9737 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This is a custom node utility package developed for ComfyUI. Initially created f ## 最新更新 / Last Update ### [未发布 Unreleased] +- 数学表达式计算节点支持三角函数、对数指数和常量(`sin`/`cos`/`tan`/`atan2`/`sqrt`/`log`/`exp`/`pi`/`e` 等),三角函数以弧度为单位,可用 `radians()` 转换 +- AbcMath now supports trigonometric, logarithmic and exponential functions plus constants (`sin`, `cos`, `tan`, `atan2`, `sqrt`, `log`, `exp`, `pi`, `e`, …); trigonometry works in radians, convert with `radians()` - 批量图片载入节点新增 `filenames` 输出(原文件名),配合自定义图像保存节点新增的 `exact_filename` 开关,即可按原文件名保存批处理结果 - Load Image Folder gained a `filenames` output, and Custom Save Image an `exact_filename` toggle, so batch results can be saved under their original names @@ -187,15 +189,19 @@ https://github.com/user-attachments/assets/b8d1d3f0-04d1-46c5-968a-e433778b73e6 - 支持动态解析数学表达式。 - 提供多种运算符和函数支持(加、减、乘、除、幂、取模等)。 - 支持变量 `a`、`b`、`c` 的灵活输入(数字或数组形状)。 -- 内置常用数学函数(`min`、`max`、`round`、`sum`、`len` 等)。 -- 自动处理 NaN 值,确保结果稳定性。 +- 内置常用数学函数(`min`、`max`、`round`、`sum`、`len`、`abs`、`sqrt`、`floor`、`ceil`、`hypot` 等)。 +- 支持三角函数与对数指数(`sin`、`cos`、`tan`、`asin`、`acos`、`atan`、`atan2`、`sinh`、`cosh`、`tanh`、`exp`、`log`、`log10`、`log2`),以及常量 `pi`、`e`、`tau`。 +- 三角函数以弧度为单位,可用 `radians()` / `degrees()` 转换,例如 `sin(radians(a))`。 +- 自动处理 NaN 和无穷值,确保结果稳定性。 - 输出整数和浮点数两种格式。 - 适用于复杂计算场景。 - Supports dynamic parsing of mathematical expressions. - Provides a wide range of operators and functions (addition, subtraction, multiplication, division, power, modulo, etc.). - Flexible input for variables `a`, `b`, and `c` (numbers or array shapes). -- Built-in common math functions (`min`, `max`, `round`, `sum`, `len`, etc.). -- Automatically handles NaN values to ensure result stability. +- Built-in common math functions (`min`, `max`, `round`, `sum`, `len`, `abs`, `sqrt`, `floor`, `ceil`, `hypot`, etc.). +- Trigonometric, exponential and logarithmic functions (`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`, `cosh`, `tanh`, `exp`, `log`, `log10`, `log2`), plus the constants `pi`, `e` and `tau`. +- Trigonometric functions work in radians; use `radians()` / `degrees()` to convert, e.g. `sin(radians(a))`. +- Automatically handles NaN and infinite values to ensure result stability. - Outputs results in both integer and float formats. - Suitable for complex calculation scenarios. diff --git a/nodes/abc_math.py b/nodes/abc_math.py index 3c24e12..9a53a0c 100644 --- a/nodes/abc_math.py +++ b/nodes/abc_math.py @@ -67,6 +67,34 @@ class AbcMath: 'round': round, 'sum': sum, 'len': len, + 'abs': abs, + # 三角函数,参数与返回值均为弧度;要用角度先套 radians()/degrees() + 'sin': math.sin, + 'cos': math.cos, + 'tan': math.tan, + 'asin': math.asin, + 'acos': math.acos, + 'atan': math.atan, + 'atan2': math.atan2, + 'sinh': math.sinh, + 'cosh': math.cosh, + 'tanh': math.tanh, + 'degrees': math.degrees, + 'radians': math.radians, + 'sqrt': math.sqrt, + 'exp': math.exp, + 'log': math.log, + 'log10': math.log10, + 'log2': math.log2, + 'floor': math.floor, + 'ceil': math.ceil, + 'hypot': math.hypot, + } + # 常量,和 a/b/c 一样按名字取值 + constants = { + 'pi': math.pi, + 'e': math.e, + 'tau': math.tau, } @@ -82,6 +110,8 @@ class AbcMath: return b if node.id == "c": return c + if node.id in constants: + return constants[node.id] elif isinstance(node, ast.BinOp): return operators[type(node.op)](eval_(node.left), eval_(node.right)) elif isinstance(node, ast.UnaryOp): @@ -113,7 +143,9 @@ class AbcMath: result = eval_(parsed_expression.body) - if math.isnan(result): + # sqrt(-1) 之类会抛异常走到 except;log(0) 会得到 -inf, + # 这里一并挡掉,避免 int() 直接崩掉。 + if not isinstance(result, (int, float)) or math.isnan(result) or math.isinf(result): result = 0.0