数学 - 映射数字

发布于 2024-07-10 01:24:14 字数 119 浏览 7 评论 0原文

如何将 a 和 b 之间的数字线性映射到 c 和 d 之间。

也就是说,我希望 2 到 6 之间的数字映射到 10 到 20 之间的数字......但我需要广义的情况。

我的脑子炸了。

How do I map numbers, linearly, between a and b to go between c and d.

That is, I want numbers between 2 and 6 to map to numbers between 10 and 20... but I need the generalized case.

My brain is fried.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

颜漓半夏 2024-07-17 01:24:32
int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);

当然,还有除以零的检查。

int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);

With checks on divide by zero, of course.

妳是的陽光 2024-07-17 01:24:30

其中 X 是从 A-B 映射到 C-D 的数字,Y 是结果:
取线性插值公式 lerp(a,b,m)=a+(m *(b-a)),并用 CD 代替 ab 得到 Y=C+(m*(D -C))。 然后,用 (X-A)/(B-A< 代替 m /strong>) 得到 Y=C+(((X-A)/( B-A))*(D-C))。 这是一个不错的地图功能,但可以简化。 取出 (D-C) 部分,并将其放入被除数内,得到 Y=C+( ((X-A)*(D-C))/(B >-A))。 这给了我们另一个可以简化的部分,(X-A)*(D-C),其中等于 (X*D)-(X*C)-(A >*D)+(A*C)。 将其代入,您将得到 Y=C+(((X*D)-(X*C)-(A*D)+(A* C))/(B-A))。 您需要做的下一件事是添加 +C 位。 为此,您将 C 乘以 (B-A) 即可得到 ((B* C)-(A*C)),并将其移入股息,得到Y=(((X*D)-(X*C)-(A* D)+(A*C)+(B*C)-( >A*C))/(B-A))。 这是多余的,包含 +(A*C) 和 -(A*C),这相互抵消。 删除它们,您将得到最终结果:Y=((X*D)-(X *C)-(A*D)+(B*C) )/(B-A)

TL;DR:标准地图函数,Y=C+(( (X-A)/(B-A))*(D -C)),可以简化为Y=((X*D)-(X*C)-(A*D)+(B* C))/(B-A)

Where X is the number to map from A-B to C-D, and Y is the result:
Take the linear interpolation formula, lerp(a,b,m)=a+(m*(b-a)), and put C and D in place of a and b to get Y=C+(m*(D-C)). Then, in place of m, put (X-A)/(B-A) to get Y=C+(((X-A)/(B-A))*(D-C)). This is an okay map function, but it can be simplified. Take the (D-C) piece, and put it inside the dividend to get Y=C+(((X-A)*(D-C))/(B-A)). This gives us another piece we can simplify, (X-A)*(D-C), which equates to (X*D)-(X*C)-(A*D)+(A*C). Pop that in, and you get Y=C+(((X*D)-(X*C)-(A*D)+(A*C))/(B-A)). The next thing you need to do is add in the +C bit. To do that, you multiply C by (B-A) to get ((B*C)-(A*C)), and move it into the dividend to get Y=(((X*D)-(X*C)-(A*D)+(A*C)+(B*C)-(A*C))/(B-A)). This is redundant, containing both a +(A*C) and a -(A*C), which cancel each other out. Remove them, and you get a final result of: Y=((X*D)-(X*C)-(A*D)+(B*C))/(B-A)

TL;DR: The standard map function, Y=C+(((X-A)/(B-A))*(D-C)), can be simplified down to Y=((X*D)-(X*C)-(A*D)+(B*C))/(B-A)

淡淡離愁欲言轉身 2024-07-17 01:24:30

如果您的范围从 [a 到 b] 并且您想要将其映射到 [c 到 d],其中 x 是您要映射的值
使用这个公式(线性映射)

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

if your range from [a to b] and you want to map it in [c to d] where x is the value you want to map
use this formula (linear mapping)

double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)
难得心□动 2024-07-17 01:24:27

第一个范围上的每个单位间隔占用第二个范围上的 (dc)/(ba)“空间”。

Pseudo:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

如何处理舍入取决于您。

Each unit interval on the first range takes up (d-c)/(b-a) "space" on the second range.

Pseudo:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

How you handle the rounding is up to you.

弥枳 2024-07-17 01:24:25

https://rosettacode.org/wiki/Map_range

[a1, a2] => [b1, b2]

if s in range of [a1, a2]

then t which will be in range of [b1, b2]

t= b1 + ((s- a1) * (b2-b1))/ (a2-a1)

https://rosettacode.org/wiki/Map_range

[a1, a2] => [b1, b2]

if s in range of [a1, a2]

then t which will be in range of [b1, b2]

t= b1 + ((s- a1) * (b2-b1))/ (a2-a1)
晨敛清荷 2024-07-17 01:24:24

除了 @PeterAllenWebb 答案之外,如果您想反转结果,请使用以下命令:

reverseX = (B-A)*(Y-C)/(D-C) + A

In addition to @PeterAllenWebb answer, if you would like to reverse back the result use the following:

reverseX = (B-A)*(Y-C)/(D-C) + A
北笙凉宸 2024-07-17 01:24:23

顺便说一句,这与经典的摄氏度转换为华氏度的问题相同,您想要映射等于 0 - 100 (C) 到 32 - 212 (F) 的数字范围。

As an aside, this is the same problem as the classic convert celcius to farenheit where you want to map a number range that equates 0 - 100 (C) to 32 - 212 (F).

〃温暖了心ぐ 2024-07-17 01:24:22

最好在 java.lang.Math 类中拥有此功能,因为这是一个广泛需要的功能,并且在其他语言中也可用。
这是一个简单的实现:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}

我将此代码放在这里作为未来自己的参考,可能会对某人有所帮助。

It would be nice to have this functionality in the java.lang.Math class, as this is such a widely required function and is available in other languages.
Here is a simple implementation:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}

I am putting this code here as a reference for future myself and may be it will help someone.

黑色毁心梦 2024-07-17 01:24:21

除以得到两个范围大小之间的比率,然后减去初始范围的起始值,乘以该比率并加上第二个范围的起始值。 换句话说,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

这将第一个范围中的数字均匀分布在第二个范围中。

Divide to get the ratio between the sizes of the two ranges, then subtract the starting value of your inital range, multiply by the ratio and add the starting value of your second range. In other words,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

This evenly spreads the numbers from the first range in the second range.

似梦非梦 2024-07-17 01:24:19

如果你的数字 X 落在 A 和 B 之间,并且你希望 Y 落在 C 和 D 之间,你可以应用以下线性变换:

Y = (X-A)/(B-A) * (D-C) + C

这应该给你你想要的,尽管你的问题有点模棱两可,因为你也可以沿相反方向映射间隔。 只要注意被零除就应该没问题。

If your number X falls between A and B, and you would like Y to fall between C and D, you can apply the following linear transform:

Y = (X-A)/(B-A) * (D-C) + C

That should give you what you want, although your question is a little ambiguous, since you could also map the interval in the reverse direction. Just watch out for division by zero and you should be OK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文