diff --git a/README.md b/README.md index 936cdbb..1b57792 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ # comfyui-lerp-node A simple math node that performs linear interpolation between a base range and a mapped range. + +## SimpleLERP + +Maps an input `value` from an input range `[in_min, in_max]` onto an output range +`[out_min, out_max]`: + +``` +t = (value - in_min) / (in_max - in_min) +output = out_min + t * (out_max - out_min) +``` + +Found in the node browser under the **math** category as **Simple LERP**. + +### Inputs + +| Name | Type | Default | Description | +|-----------|---------|---------|--------------------------------------------------------------------| +| `value` | FLOAT | 0.0 | The value to map. | +| `in_min` | FLOAT | 0.0 | Lower bound of the input range. | +| `in_max` | FLOAT | 1.0 | Upper bound of the input range. | +| `out_min` | FLOAT | 0.0 | Lower bound of the output range. | +| `out_max` | FLOAT | 1.0 | Upper bound of the output range. | +| `clamp` | BOOLEAN | False | If true, hold the result within the output range instead of extrapolating. | + +### Output + +| Name | Type | Description | +|---------|-------|----------------------------| +| `value` | FLOAT | The interpolated result. | + +Notes: +- With `clamp` off, inputs outside `[in_min, in_max]` extrapolate beyond the output range. +- Inverted ranges (e.g. `out_min > out_max`) are supported. +- If `in_min == in_max`, the result is `out_min` (no division by zero). diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..4542a82 --- /dev/null +++ b/__init__.py @@ -0,0 +1,3 @@ +from .node import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS + +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/node.py b/node.py new file mode 100644 index 0000000..50c3392 --- /dev/null +++ b/node.py @@ -0,0 +1,40 @@ +class SimpleLERP: + """Linear interpolation: map a value from an input range to an output range.""" + + @classmethod + def INPUT_TYPES(cls): + flt = {"default": 0.0, "min": -1e9, "max": 1e9, "step": 0.01} + return { + "required": { + "value": ("FLOAT", flt), + "in_min": ("FLOAT", {**flt, "default": 0.0}), + "in_max": ("FLOAT", {**flt, "default": 1.0}), + "out_min": ("FLOAT", {**flt, "default": 0.0}), + "out_max": ("FLOAT", {**flt, "default": 1.0}), + "clamp": ("BOOLEAN", {"default": False}), + } + } + + RETURN_TYPES = ("FLOAT",) + RETURN_NAMES = ("value",) + FUNCTION = "lerp" + CATEGORY = "math" + + def lerp(self, value, in_min, in_max, out_min, out_max, clamp): + in_span = in_max - in_min + if in_span == 0: + # Degenerate input range: nothing to interpolate across. + result = out_min + else: + t = (value - in_min) / in_span + result = out_min + t * (out_max - out_min) + + if clamp: + lo, hi = min(out_min, out_max), max(out_min, out_max) + result = max(lo, min(hi, result)) + + return (result,) + + +NODE_CLASS_MAPPINGS = {"SimpleLERP": SimpleLERP} +NODE_DISPLAY_NAME_MAPPINGS = {"SimpleLERP": "Simple LERP"}