我有点被困在这里了,我想这有点脑筋急转弯。如果我的数字在0.5到1之间,我如何将其规范化到0到1之间?
谢谢你的帮助,也许我只是有点慢,因为我已经连续工作了24个小时,O_O
发布于 2009-09-24 13:24:22
其他人给你提供了公式,但没有提供工作。下面是如何处理这样的问题的方法。你可能会发现这比仅仅知道答案更有价值。
为了将[0.5, 1]映射到[0, 1],我们将寻找形式为x -> ax + b的线性映射。我们将要求将端点映射到端点,并保留该顺序。
方法一:将端点映射到端点并保留顺序的要求意味着将0.5映射到0,将1映射到1
a * (0.5) + b = 0 (1)
a * 1 + b = 1 (2)这是一个线性方程组,可以通过将方程(1)乘以-2并将方程(1)与方程(2)相加来求解。在这样做的时候,我们得到了b = -1,并将它代入方程(2),我们得到了a = 2。因此,map x -> 2x - 1将完成此任务。
方法二:通过两点(x1, y1)和(x2, y2)的直线的斜率是
(y2 - y1) / (x2 - x1).在这里,我们将使用点(0.5, 0)和(1, 1)来满足端点映射到端点并且映射保持顺序的要求。因此,斜率是
m = (1 - 0) / (1 - 0.5) = 1 / 0.5 = 2.我们知道(1, 1)是直线上的一个点,因此通过直线方程的点斜率形式,我们可以得到
y - 1 = 2 * (x - 1) = 2x - 2所以
y = 2x - 1.我们再一次看到,x -> 2x - 1是一个可以完成此任务的映射。
发布于 2009-09-24 12:30:33
减去0.5 (给出一个0-0.5的新范围),然后乘以2。
double normalize( double x )
{
// I'll leave range validation up to you
return (x - 0.5) * 2;
}发布于 2009-09-25 13:23:20
添加另一个通用答案。
如果要将线性范围A..B映射到C..D,可以应用以下步骤:
移动范围,使下限为0。(从两个边界减去A:
[A..B] -> [0..B-A]缩放范围,使其为0..1。(除以上限):
[0..B-A] -> [0..1]缩放范围,使其具有新范围的长度,即D-C。(与D-C相乘):
[0..1] -> [0..D-C]移动范围,使下限为C (将C添加到边界):
[0..D-C] -> [C..D]将其合并到一个公式中,我们得到:
(D-C)*(X-A)
X' = ----------- + C
(B-A)在你的例子中,A=0.5,B=1,C=0,D=1,你会得到:
(X-0.5)
X' = ------- = 2X-1
(0.5)请注意,如果您必须将大量X转换为X',则可以将公式更改为:
(D-C) C*B - A*D
X' = ----- * X + ---------
(B-A) (B-A)看看非线性范围也是很有趣的。您可以采取相同的步骤,但需要额外的步骤将线性范围转换为非线性范围。
https://stackoverflow.com/questions/1471370
复制相似问题