About Monkey 2 › Forums › Monkey 2 Code Library › TransformRange – scale value from one range to another
Tagged: range, scale, transform, TransformRange, translate
This topic contains 2 replies, has 2 voices, and was last updated by
DruggedBunny
8 months, 4 weeks ago.
-
AuthorPosts
-
July 24, 2018 at 12:11 am #15127
Had to look this one up! Main intended use for me is to scale joystick input values (-1.0 to 1.0) into other ranges (eg. 0.0 to 1.0)…
Monkey123456789101112131415161718192021222324252627282930313233343536#Import "<std>"' NB. Input range (from_max - from_min) must be non-zero -- mathematically impossible to scale a zero-size range into a non zero-size range!Function TransformRange:Float (input_value:Float, from_min:Float, from_max:Float, to_min:Float, to_max:Float)' Algorithm via jerryjvl at https://stackoverflow.com/questions/929103/convert-a-number-range-to-another-range-maintaining-ratioLocal from_delta:Float = from_max - from_min ' Input range, eg. 0.0 - 1.0Local to_delta:Float = to_max - to_min ' Output range, eg. 5.0 - 10.0Assert (from_delta <> 0.0, "TransformRange: Invalid input range!")Return (((input_value - from_min) * to_delta) / from_delta) + to_minEndFunction Main ()' Transform value of 0.5 in range 0.0 - 1.0 into range 0.5 - 1.0...Local value:Float = 0.5 ' Half-way into input range 0.0 - 1.0Local from_range_min:Float = 0.0Local from_range_max:Float = 1.0Local to_range_min:Float = 5.0Local to_range_max:Float = 10.0' Answer = 7.5 -- halfway between 5 and 10.Print TransformRange (value, from_range_min, from_range_max, to_range_min, to_range_max)EndNot sure if the correct mathematical term is ‘transform’, but that’s what I’m calling it…
July 24, 2018 at 3:00 pm #15138Useful function!
I made this func a bit universal – by using generic for any number types.
Monkey1234567891011Function TransformRange<T>:T (input_value:T, from_min:T, from_max:T, to_min:T, to_max:T) Where T Implements INumeric' Algorithm via jerryjvl at https://stackoverflow.com/questions/929103/convert-a-number-range-to-another-range-maintaining-ratioLocal from_delta := from_max - from_min ' Input range, eg. 0.0 - 1.0Local to_delta := to_max - to_min ' Output range, eg. 5.0 - 10.0Assert (from_delta <> Null, "TransformRange: Invalid input range!")Return (((input_value - from_min) * to_delta) / from_delta) + to_minEndNote 1: I replaced Assert (from_delta <> 0.0,... with Assert (from_delta <> Null,... to have comparison with _0_ for int-based and 0.0 for float-based types.
Note 2: Seems that comparison floats with any concrete number is a bad idea, because 0.0 is about 0.0000000001 or so. But it works!
Note 3: Bad idea to use it for integers because of division operation… so maybe better where-clause would be Where T=Float Or T=Double.
July 24, 2018 at 6:05 pm #15141Nice, I briefly thought about doing <T> but didn’t really need it.
Not really familiar with Where, but I think I see how that works, which is cool.
I’d say it’s a bug, though, if float zero ever evaluates to 0.0000000000001! Although floats can definitely not represent all numbers, and direct value comparisons are generally a bad idea, floating point zero should still always be 0.0[… 0] no matter what — all bits being set to zero.
Already found mine really useful, great for getting finer control from joystick inputs!
-
AuthorPosts
You must be logged in to reply to this topic.