Math Utilities
Math Utilities
Numeric helpers Verse lacks out of the box: Modulo, ClampInt/Float, SafeDivide, RoundTo, LerpFloat, and a zero-safe vector SafeNormalize.
Original, compile-verified Verse by Bizanator (Biloxi Studios). Clean-room sample you can drop into a UEFN project and adapt.
# Math Utilities — Biloxi Studios Inc.
#
# Generic numeric helpers Verse doesn't ship out of the box: integer modulo,
# clamping, safe division, rounding to N decimals, linear interpolation, and a
# zero-safe vector normalize. Dependency-free.
#
# Teaches: <decides>/<transacts> effects, Int[]/Round[]/Floor[] failable casts,
# guarding division by zero, and basic vector math.
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
math_utils<public> := module:
# Integer modulo (remainder). Verse has no `%` operator, so we derive it from
# integer division. Returns 0 when Divisor is 0 rather than failing.
Modulo<public>(Dividend:int, Divisor:int)<transacts>:int =
if (Divisor <> 0, Q := Quotient[Dividend, Divisor]):
return Dividend - Q * Divisor
0
# Clamp an int into [Low, High].
ClampInt<public>(Value:int, Low:int, High:int)<transacts>:int =
Max(Low, Min(Value, High))
# Clamp a float into [Low, High].
ClampFloat<public>(Value:float, Low:float, High:float)<transacts>:float =
Max(Low, Min(Value, High))
# Divide two floats, returning Fallback instead of dividing by zero.
SafeDivide<public>(Dividend:float, Divisor:float, Fallback:float)<transacts>:float =
if (Divisor <> 0.0):
return Dividend / Divisor
Fallback
# Round a float to Decimals places (e.g. RoundTo(3.14159, 2) ≈ 3.14).
RoundTo<public>(Value:float, Decimals:int)<transacts>:float =
Factor := Pow(10.0, Decimals * 1.0)
if (Rounded := Round[Value * Factor]):
return (Rounded * 1.0) / Factor
Value
# Linear interpolation between A and B by Alpha in [0, 1]. (Named LerpFloat to
# avoid colliding with the built-in Verse Lerp.)
LerpFloat<public>(A:float, B:float, Alpha:float)<transacts>:float =
Clamped := ClampFloat(Alpha, 0.0, 1.0)
A + (B - A) * Clamped
# Normalize a vector, returning the zero vector when the input has no length
# (avoids a divide-by-zero).
SafeNormalize<public>(Vec:vector3)<transacts>:vector3 =
Length := Vec.Length()
if (Length > 0.0):
return Vec / Length
vector3{X := 0.0, Y := 0.0, Z := 0.0}