Convert arbitrary length to a value between -1.0 a

2020-07-11 08:49发布

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.

标签: math range
7条回答
男人必须洒脱
2楼-- · 2020-07-11 08:54
-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

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2020-07-11 08:55

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).

查看更多
男人必须洒脱
4楼-- · 2020-07-11 09:04

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.

查看更多
Luminary・发光体
5楼-- · 2020-07-11 09:07

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

(XCoordinate - 220) / 220.0
查看更多
何必那么认真
6楼-- · 2020-07-11 09:09

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
查看更多
孤傲高冷的网名
7楼-- · 2020-07-11 09:15

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

(image alt text)

查看更多
登录 后发表回答