How do I convert a number and a range to another directly proportional number and range?
This question is really hard to formulate.
Let's say I have a range of 0 - 100, and the number 56.
I want to convert the number 56 to be directly proportional to the range of (0 - 3) and convert it in tsaid range.
Example: Number 50, range is (0 - 100) Output number is 1.5 in the range (0 - 3), directly proportional to what is above
Answer by SammyDee · May 31, 2017 at 09:26 PM
As long as 0 is the first number in both your ranges, you would simply divide the number in the first range by the upper limit of the first range and then multiply by the upper limit of your second range.
In your example: 56 / 100 * 3 = 1.68 So 56 in (0 - 100) would be equivalent to 1.68 in (0 - 3)
Answer by elenzil · Jun 01, 2017 at 06:56 PM
I would suggest using InverseLerp and Lerp.
float normalizedValue = Mathf.InverseLerp(range1Min, range1Max, value1);
float result = Mathf.Lerp(range2Min, range2Max, normalizedValue)
you could also combine those into a single statement if you wanted.
Answer by Max_Bol · Aug 15, 2018 at 11:29 PM
The universal way of handling this is actually quite simple, but it requires you to see the whole thing from a different perspective.
.
Here's the formula: (V × R2 ÷ R1) + (M2 - M1)
. V = the value you want to convert. R1 and R2 are both differential values of each ranges (maximum value - minimum value). M1 and M2 are both minimal values of each range.
.
For the example given, this gets (56 × 3 ÷ 100) + (0 - 0) = 1.68f.
.
Let's use the same formula to convert 56 in a range of 0 and 100 which could be a volume slider for your game into a range of -80 and 0 which is in dB (sound volume units used by Unity). (56 × 80 ÷ 100) + (-80 - 0).
.
As you can see, the differential value of the volume in dB is 80 because there 80 floating units between -80 and 0. The result to that means that a volume of 56% is at -35.2dB.
this is not correct.
consider this example:
range1 = [1, 3]
range2 = [10, 30]
vIn = 2
the input is halfway through range1, so we would expect the output to be halfway through range2: 20.
vOut = (V * R2 / R1) + ($$anonymous$$2 - $$anonymous$$1)
vOut = (2 * (30 - 10) / (3 - 1)) + (10 - 1)
vOut = (2 * 20 / 2) + 9
vOut = 29
the correct general formula is:
(V - $$anonymous$$1) * R2 / R1 + $$anonymous$$2
vOut = (V - $$anonymous$$1) * R2 / R1 + $$anonymous$$2
vOut = (2 - 1) * (30 - 10) / (3 - 1) + 10
vOut = 1 * 20 / 2 + 10
vOut = 20
You are right... I'm sorry for misleading with my erronous formula. Still, I couldn't get your formula to give the right value in converting 56% (vIn 56 on [0,100] range) into [-80,0] range. Could you elaborate with that example? (56-0) * (100-0) / (0 + 80) - 80 = -10 while it should be between -30 and -40 (-40 being 50%).
But, I'll write it to my defense... while my formula is wrong, for some strange reason, it works 100% of the times I needed it. It's used over 10 times and, each time, it gives out the exact value that I need. I'm using it to manage volumes, converting mouse's position into a different kind of float range, etc.
=== A $$anonymous$$O$$anonymous$$ENT LATER ===
Important note, what's following isn't really your typical maths. It's something that can be quite puzzling for anyone who believes that numbers can only be a straight and ruled thing.
This really puzzled me for a couple of hours and I have found out "why" it works in my circumstances and not in some others. Funny as it might sounds, it all came back an argument I had with a $$anonymous$$ath $$anonymous$$cher at High school. Basically, I made him realize that there are 2 kinds of math: Logical and Physical.
The reason why my formula worked for me is because it's not wrong if you consider something like an Integer value. As integer value can't be divided into two identical values if it's an odd number, it gets easily wonky when you try to divide the integer 3 by 2. (If you divide an integer of 3 by 2, you get 2 as a result as it's impossible to result with 1.5 with integers.) It seems that all the cases in which I used my formula were all cases I call "bubble cases".
Now, what happens if you play with both integer (which can't be divided in usage) and floats? Yeah, it's a mess! In my cases, the formula worked because I'm converting a value within a certain range of masses and because that value represent a mass by itself.
In the example of [1,3] in range with value of 2 converted to [10,30], in terms of space and masses, 2 becomes a mass that isn't a single unit anymore.
Each of those has a mass of 1 unit each.
|1|2|3|
If you extend it to |10| [...] |30|, that means you got 21 units involved afterward.
|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|
Notice how it's not 20, but 21 units? That's similar to the concept where Lenght() or Count() always return 1 number above the last "id" available in an Array[ ] or a List< >. That's because the length/count doesn't includes 0 in the units counted while the Array[ ] and List< > do have a instance of 0.
If we return back to the list of 10 to 30 units.
|1|**2**|3|
becomes...
|10|11|12|13|14|15|16|**17**|**18**|**19**|**20**|**21**|**22**|**23**|24|25|26|27|28|29|30|
What's in **bold** is what has become of 2 when stretched. Each of the 3 units became 7 units each. So, the "value" that was at the end of 2 in [1,3] is now at the end of 23 in [10,30]. (2*21/3)+(10-1) = 23.
heya - yeah, i noticed that your math worked for the two values i checked it against as well, which were 0 and 100. that surprised me.
I couldn't get your formula to give the right value in converting 56% (vIn 56 on [0,100] range) into [-80,0] range. Could you elaborate with that example? (56-0) * (100-0) / (0 + 80) - 80 = -10 while it should be between -30 and -40 (-40 being 50%).
you multiplied by R1 and divided by R2, ins$$anonymous$$d of the reverse.
range1 = [ 0, 100]
range2 = [-80, 0]
r1 = 100
r2 = 80
v1 = 56
v2 = (v1 - m1) * r2 / r1 + m2
v2 = (56 - 0) * 80 / 100 + -80
v2 = -35.2
Answer by webertbrito · Apr 03, 2020 at 05:19 PM
Hi, it's been posted a while now but I have an issue with the same nature but the formula does not apply. What if the initial or final range is reverse? For exemple:
Initial range: [237,12] Final range: [14,114]
How do I convert a number from initial range to final range?
can you describe the output you want for an example input ? eg, if the input is 237, do you want 14 or 114 ?
If you go the route of inverselerp() / lerp(), you can reverse the direction of the interpolation by subtracting the normalized value from 1. eg
float normalizedValue = $$anonymous$$athf.InverseLerp(range1$$anonymous$$in, range1$$anonymous$$ax, value1);
float flippedNormalizedValue = 1.0f - normalizedValue;
float result = $$anonymous$$athf.Lerp(range2$$anonymous$$in, range2$$anonymous$$ax, flippedNormalizedValue )