Convert arbitrary length to a value between -1.0 a

2020-07-11 08:48发布

问题:

How can I convert a length into a value in the range -1.0 to 1.0?

Example: my stage is 440px in length and accepts mouse events. I would like to click in the middle of the stage, and rather than an output of X = 220, I'd like it to be X = 0. Similarly, I'd like the real X = 0 to become X = -1.0 and the real X = 440 to become X = 1.0.

I don't have access to the stage, so i can't simply center-register it, which would make this process a lot easier. Also, it's not possible to dynamically change the actual size of my stage, so I'm looking for a formula that will translate the mouse's real X coordinate of the stage to evenly fit within a range from -1 to 1.

回答1:

-1 + (2/440)*x

where x is the distance

So, to generalize it, if the minimum normalized value is a and the maximum normalized value is b (in your example a = -1.0, b = 1.0 and the maximum possible value is k (in your example k = 440):

a + x*(b-a)/k

where x is >= 0 and <= k



回答2:

This is essentially two steps:

  1. Center the range on 0, so for example a range from 400 to 800 moves so it's from -200 to 200. Do this by subtracting the center (average) of the min and max of the range
  2. Divide by the absolute value of the range extremes to convert from a -n to n range to a -1 to 1 range. In the -200 to 200 example, you'd divide by 200


回答3:

Doesn't answer your question, but for future googlers looking for a continuous monotone function that maps all real numbers to (-1, 1), any sigmoid curve will do, such as atan or a logistic curve:

f(x) = atan(x) / (pi/2)  
f(x) = 2/(1+e-x) - 1



回答4:

(x - 220) / 220 = new X

Is that what you're looking for?



回答5:

You need to shift the origin and normalize the range. So the expression becomes

(XCoordinate - 220) / 220.0


回答6:

handling arbitrary stage widths (no idea if you've got threads to consider, which might require mutexes or similar depending on your language?)

stageWidth = GetStageWidth(); // which may return 440 in your case
clickedX = MouseInput(); // should be 0 to 440
x = -1.0 + 2.0 * (clickedX / stageWidth); // scale to -1.0 to +1.0

you may also want to limit x to the range [-1,1] here?

if ( x < -1 ) x = -1.0;
if ( x >  1 ) x =  1.0;

or provide some kind of feedback/warning/error if its out of bounds (only if it really matters and simply clipping it to the range [-1,1] isn't good enough).



回答7:

You have an interval [a,b] that you'd like to map to a new interval [c,d], and a value x in the original coordinates that you'd like to map to y in the new coordinates. Then:

y = c + (x-a)*(c-d)/(b-a)

And for your example with [a,b] = [0,440] and [c,d] = [-1,1], with x=220:

y = -1 + (220-0)*(1 - -1)/(440-0)
  = 0

and so forth.

By the way, this works even if x is outside of [a,b]. So as long as you know any two values in both systems, you can convert any value in either direction.



标签: math range