这个方法保证将任何范围映射到任何范围
我编写了这个方法,严格按照代数公式来映射一个范围内的数字到另一个范围。计算过程中使用双精度浮点数以保持精度,最后会返回一个指定小数位数的双精度浮点数。
在定义范围的低端和高端时,并不需要将其命名为“low”或“high”,因为无论哪一端的值较低或较高,该方法都能正确地映射数字。
例如,如果你将任何范围定义为[-100到300]或[300到-100],并没有任何区别。重新映射的结果仍然准确。
以下是如何在你的代码中使用该方法:
mapOneRangeToAnother(myNumber, fromRangeA, fromRangeB, toRangeA, toRangeB, decimalPrecision)
以下是如何使用该方法的示例:
源范围:-400 到 800
目标范围:10000 到 3500
重新映射的数字:250
double sourceA = -400;
double sourceB = 800;
double destA = 10000;
double destB = 3500;
double myNum = 250;
double newNum = mapOneRangeToAnother(myNum,sourceA,sourceB,destA,destB,2);
Result: 6479.17
如果你需要一个整数返回值,只需将精度设置为0位小数,并将结果转换为int类型,像这样:
int myResult = (int) mapOneRangeToAnother(myNumber, 500, 200, -350, -125, 0);
或者你可以声明该方法返回一个整数,并移除
decimalPrecision参数,然后将最后两行改为:
int calcScale = (int) Math.pow(10, 0);
return (int) Math.round(finalNumber * calcScale) / calcScale;
在 OP 的问题中,他们会像这样使用该函数:
int myResult = (int) mapOneRangeToAnother(input, input_start, input_end, output_start, output_end, 0);
这是方法:
编辑:正如 @CoryGross 指出的那样,如果将相同的数字传入到 from
范围的两个端点中,就会发生除零错误。而且由于该方法应该根据两个数字范围计算一个新的数字,如果任一范围的端点具有相同的值,计算结果将毫无意义,因此在这种情况下需要返回 null。
此示例是用 Java 编写的
public static Double mapOneRangeToAnother(double sourceNumber, double fromA, double fromB, double toA, double toB, int decimalPrecision ) {
double deltaA = fromB - fromA;
double deltaB = toB - toA;
if(deltaA == 0 || deltaB == 0) {
return null;
}
double scale = deltaB / deltaA;
double negA = -1 * fromA;
double offset = (negA * scale) + toA;
double finalNumber = (sourceNumber * scale) + offset;
int calcScale = (int) Math.pow(10, decimalPrecision);
return (double) Math.round(finalNumber * calcScale) / calcScale;
}
在我的使用情况中,我需要淡化JavaFX Control的不透明度,但由于不透明度是从0到1的数字,所以我只需使用该方法重新映射范围1到100(基于一个for循环,它将int从0增加到100)到范围0到1,并且效果完美。
虽然现在我知道我可以通过将增量从1更改为像.01这样的值来创建我的循环,就像这样:
for(double x=0; x<=1; x+=.01 {
}
我只是为了提醒那些可能在做类似于我所做的事情的人。这种方法如描述的那样完美地运作。
:-)