Ben Traje
← Back to houdini

How to Map and Fit Point Numbers to Custom Ranges in Houdini VEX

31 Aug 26 (2mo ago)

Remapping Point Indices in Houdini VEX

When working with geometry in Houdini, normalizing point numbers (@ptnum) against the total point count (@numpt) is a foundational technique for creating procedural gradients, controlling falloffs, and driving downstream attributes.

The Common Pitfall: Integer Division & Range Mappings

In VEX, @ptnum and @numpt are integers. Dividing two integers can cause precision errors if not cast to floating-point numbers. Additionally, manually scaling fractions can lead to syntax issues and calculation errors.

Here is how to properly normalize and remap point ranges in a Point Wrangle.

1. Basic Normalization (0 to 1)

To map point indices linearly from 0.0 (first point) to 1.0 (last point):

// Cast to float to avoid integer division truncation
float normalized = (float)@ptnum / (float)(@numpt - 1);

// Assign to a custom point attribute
@my_val = normalized;

2. Inverting the Range (1 to 0)

To make the first point @ptnum = 0 output 1.0 and the last point output 0.0:

float normalized = (float)@ptnum / (float)(@numpt - 1);
@my_val = 1.0 - normalized;

3. The Recommended Method: Using fit() or fit01()

Instead of manually multiplying and adding offsets, VEX provides built-in fitting functions that handle the interpolation safely and cleanly.

Mapping to an Arbitrary Range (e.g., 0.1 to 1.0)

// Using fit01 to remap a normalized 0-1 value to 0.1 - 1.0
float normalized = (float)@ptnum / (float)(@numpt - 1);
@my_val = fit01(normalized, 0.1, 1.0);

Alternative Direct fit() Syntax

// Remap directly from index domain [0, @numpt - 1] to target domain [0.1, 1.0]
@my_val = fit((float)@ptnum, 0.0, (float)(@numpt - 1), 0.1, 1.0);

Verification Example (5 Total Points)

When @numpt = 5, indices run from 0 to 4:

@ptnumNormalized (ptnum / 4.0)fit01(norm, 0.1, 1.0)
00.000.100
10.250.325
20.500.550
30.750.775
41.001.000