代码如下:
/**
* WaterLevelInterpolator 实现了水位插值的功能,可以根据给定的数据点进行线性插值计算目标距离处的水位。
*/
public class WaterLevelInterpolator {
/** 保存数据点的距离与水位的映射关系 */
private final Map<Double, Double> dataPoints = new HashMap<>();
/**
* 构造函数,初始化水位插值器,需要提供两个数据点的距离和水位信息。
*
* @param distance1 第一个数据点的距离
* @param waterLevel1 第一个数据点的水位
* @param distance2 第二个数据点的距离
* @param waterLevel2 第二个数据点的水位
*/
public WaterLevelInterpolator(double distance1, double waterLevel1, double distance2, double waterLevel2) {
dataPoints.put(distance1, waterLevel1);
dataPoints.put(distance2, waterLevel2);
}
/**
* 根据目标距离进行水位插值计算。
*
* @param targetDistance 目标距离
* @return 在目标距离处计算得到的水位
*/
public double interpolateWaterLevel(double targetDistance) {
// 如果目标距离正好是已知数据点之一,则直接返回该数据点对应的水位
if (dataPoints.containsKey(targetDistance)) {
return dataPoints.get(targetDistance);
}
// 初始化较小距离和较大距离为负无穷和正无穷
double lowerDistance = Double.NEGATIVE_INFINITY;
double upperDistance = Double.POSITIVE_INFINITY;
// 遍历数据点,找到目标距离所在的区间
for (double distance : dataPoints.keySet()) {
if (distance < targetDistance && distance > lowerDistance) {
lowerDistance = distance;
}
if (distance > targetDistance && distance < upperDistance) {
upperDistance = distance;
}
}
// 获取较小距离和较大距离对应的水位
double lowerWaterLevel = dataPoints.get(lowerDistance);
double upperWaterLevel = dataPoints.get(upperDistance);
// 使用线性插值计算目标距离处的水位
double v = lowerWaterLevel + (targetDistance - lowerDistance) *
(upperWaterLevel - lowerWaterLevel) / (upperDistance - lowerDistance);
// 对计算结果进行四舍五入保留两位小数,并返回
return NumberUtil.round(v, 2).doubleValue();
}
}
示例:
WaterLevelInterpolator t1 = new WaterLevelInterpolator(-10, -2.5, 10, 3.7);
double r1 = t1.interpolateWaterLevel(-5);
double r2 = t1.interpolateWaterLevel(0);
double r3 = t1.interpolateWaterLevel(5);
double r4 = t1.interpolateWaterLevel(-7.9);
double r5 = t1.interpolateWaterLevel(7.8);
输出结果如下:
-0.95
0.6
2.15
-1.85
3.02