我有一个函数,它将采用一系列值,需要将其标准化为[-1,1]范围。 MathHelper.Clamp()
只获取超出范围的值,并将它们设置为超出范围。 XNA或C#有什么能满足我的需求吗? (我正在查看文档,但找不到它。)
这是鼠标移动。值是一个刻度与下一个刻度之间的鼠标坐标的差异。我不确定它的最大值是什么。
此函数将一次取一个值 - 因此不会迭代所有值来缩放它们或查看最小值和最大值。
这就是我目前所拥有的:
// max - min cannot == 0
private float normalizeToRange(float value, float min, float max) {
return (2.0f * (value - min) / (max - min)) -1.0f;
}
答案 0 :(得分:1)
对每个值应用公式2 *(x-min)/(max-min)+ -1应该为你标准化。
(x-min)/(max-min)给出0到1之间的值
乘以2会得到0到2之间的值
减1会给出介于-1和1之间的值
答案 1 :(得分:1)
如果我正确理解了这个问题,这并不是一件非常困难的事情,但在确定标准化输出值之前,您需要知道输入值的可能范围。
例如,如果您的输入值范围为-500到+500,那么像input / 500.0这样的简单函数就可以了。
我要走出困境并假设你想要放弃这个范围的任何值范围,从-1到1,缩放设置使得最极端的输入值将完全设置为-1和1。
在这种情况下,你想迭代你的所有值(O(n),bleh!...但是你将不得不迭代你的所有值来扩展它们,无论如何,所以O(n )是不可避免的),并找到最低和最高值。确定这两个值之间的差异,将其除以输出范围,并将其用作缩放系数。对于要缩放的每个数字,添加最小输入值的倒数,按比例因子缩放,然后减去输出范围偏移。
这听起来像很多胡言乱语,所以让我举一个例子。例如,迭代后,您发现最小输入值为-300,最大输入值为700.这两者之间的差值(abs(max-min))为1000.由于输出范围大小为2(-1 1)将您的比例因子除以2 ...这使您的最终比例因子为1000/2 = 500。
然后你输入数据中的第一个点...我们会说它是334.你从中减去最小值,给你334 + 300 = 634.你用你的比例因子除以那个数,所以你得634/500 = 1.268。取这个数字,然后减去1(否则我们将缩放到(0到2),而不是(-1到1)。这会得到.268。那是你的答案。对你集合中的所有点做这个,你已经完成了。
快速健全性检查显示,如果我们尝试700(我们的集合中的最大值),我们得到((700 + 300)/ 500) - 1 = 1.同样,如果我们尝试-300,我们得到((-300) + 300)/ 500) - 1 = -1。
所以把它放到一个函数中,你很好。
如果您的输入范围不是根据您的输入而变化,而是一个已知的常数,您当然可以避免在开始时对数据进行迭代,这肯定是一件好事。
所以希望这有助于......我不会费心写出实际的功能......我猜这将是相当简单的。但如果有任何问题,或者我误解了这个概念,请告诉我。
编辑:回复您的陈述:
这是鼠标移动。值是一个刻度与下一个刻度之间的鼠标坐标的差异。我不确定它的最大值是什么。
据推测,在这个系统上有某种驱动器夹紧...如果正常的鼠标移动,比如说(-5,3),可能是鼠标根本无法记录任意大的值(1000000,1000000)用于运动。您需要了解鼠标的工作范围,以及可以产生的值,这将为您提供最小值和最大值。
答案 2 :(得分:1)
我可以通过两种方式解释您的问题。
在这两种情况下,我都将输入解释为值数组,它们将一起缩放。
在我的第一个解释中,您想计算从“原点”到N空间中的“向量”的距离(N是值的数量),然后缩放向量,使距离正好为1。 / p>
这意味着值(1,1)会缩小到大致(0.707,0.707),距离(0,0)的距离约为1。
在这种情况下,方法如下:
dist = sqrt(vector[0]^2 + vector[1]^2 + ... + vector[N-1]^2)
vector[x] = vector[x] / dist, for x=0..N-1
具有值(2,1,3)的示例向量将产生:
dist = sqrt(2^2 + 1^2 + 3^2) = sqrt(24) ~ 4.9
vector[0] = vector[0] / 4.9 ~ 0.41
vector[1] = vector[1] / 4.9 ~ 0.2
vector[2] = vector[2] / 4.9 ~ 0.61
vector = (0.41, 0.2, 0.61)
在第二种解释中,您希望最大值与0完全相差1,其余比例适合。
在这种情况下,只需找到最大值,然后将其除以(确保首先将其设为正数。)
maxValue = abs(max(vector[0], vector[1], ..., vector[N-1]))
vector[x] = vector[x] / maxValue, for x=0..N-1
与上述相同的向量将产生:
maxValue = abs(max(2, 1, 3)) = abs(3) = 3
vector[0] = vector[0] / 3 ~ 0.67
vector[1] = vector[1] / 3 ~ 0.33
vector[2] = vector[2] / 3 ~ 1
vector = (0.67, 0.33, 1)
答案 3 :(得分:0)
我相信这种扩展方法可以满足您的要求。
public static class Extension
{
public static IEnumerable<double> Normalize(this IEnumerable<double> source)
{
var min = source.Min();
var max = source.Max();
var range = max - min;
foreach (var d in source)
{
yield return ((d - min) / range) * 2 - 1;
}
}
}
答案 4 :(得分:0)
我不相信XNA有一个能为你做标准化的功能。虽然这是一个相当简单的操作......
这是我的头脑,所以测试thorgoughly :)但这是基本的想法。