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 2 months, 3 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 nonzero  mathematically impossible to scale a zerosize range into a non zerosize 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/convertanumberrangetoanotherrangemaintainingratioLocal 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 ' Halfway 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/convertanumberrangetoanotherrangemaintainingratioLocal 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 intbased and 0.0Â for floatbased 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 whereclause 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.