水位-库容曲线计算方式

master
yangzhe123 2025-09-11 14:45:30 +08:00
parent fac56264f7
commit 03d71e095a
1 changed files with 85 additions and 0 deletions

View File

@ -2,6 +2,7 @@ package com.gunshi.project.hsz.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.project.hsz.mapper.StZvarlBMapper; import com.gunshi.project.hsz.mapper.StZvarlBMapper;
import com.gunshi.project.hsz.model.StZqrlB;
import com.gunshi.project.hsz.model.StZvarlB; import com.gunshi.project.hsz.model.StZvarlB;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -72,6 +73,90 @@ public class StZvarlBService extends ServiceImpl<StZvarlBMapper, StZvarlB> {
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
} }
/**
* 线->
* ->
* @param zvarlBS
* @param rz
* @return
*/
public BigDecimal getWByZvarl(List<StZvarlB> zvarlBS, BigDecimal rz) {
// 1. 参数校验
if (zvarlBS == null || zvarlBS.isEmpty()) {
throw new IllegalArgumentException("水位-库容关系列表不能为空");
}
if (rz == null) {
throw new IllegalArgumentException("水位值不能为空");
}
// 2. 检查边界情况:如果目标水位低于最低水位或高于最高水位
BigDecimal minRz = zvarlBS.get(0).getRz();
BigDecimal maxRz = zvarlBS.get(zvarlBS.size() - 1).getRz();
if (rz.compareTo(minRz) < 0) {
// 低于最低水位,可以选择抛出异常或进行外推(这里选择抛出异常)
return BigDecimal.ZERO;
}
if (rz.compareTo(maxRz) > 0) {
// 高于最高水位,可以选择抛出异常或进行外推(这里选择抛出异常)
return BigDecimal.ZERO;
}
int l = 0;
int r = zvarlBS.size() -1;
//二分查找 由线性On时间复杂度降为Ologn
while (l <= r) {
int mid = l + (r-l) / 2;
BigDecimal midRz = zvarlBS.get(mid).getRz();
int compareResult = midRz.compareTo(rz);
if(compareResult == 0 ){
return zvarlBS.get(mid).getW();
}else if(compareResult < 0){
l = mid + 1;
}else{
r = mid - 1;
}
}
/**
* l rz
* r rz
* r x1 y1
* l x2 y2
*/
if(l < 0 || r >= zvarlBS.size()){
return BigDecimal.ZERO;
}
//获取前后差值的点
StZvarlB lowerPoint = zvarlBS.get(r);
StZvarlB upperPoint = zvarlBS.get(l);
return linearInterpolation(lowerPoint.getRz(),lowerPoint.getW(),upperPoint.getRz(),upperPoint.getW(),rz).setScale(3);
}
/**
* 线
* @param x1 1
* @param y1 1
* @param x2 2
* @param y2 2
* @param x
* @return
*/
private BigDecimal linearInterpolation(BigDecimal x1, BigDecimal y1,
BigDecimal x2, BigDecimal y2,
BigDecimal x) {
// 使用公式: y = y1 + ( (y2 - y1) / (x2 - x1) ) * (x - x1)
// 计算斜率: (y2 - y1) / (x2 - x1)
BigDecimal slope = y2.subtract(y1)
.divide(x2.subtract(x1), 10, RoundingMode.HALF_UP);
// 计算: slope * (x - x1)
BigDecimal xDiff = x.subtract(x1);
BigDecimal product = slope.multiply(xDiff);
// 计算最终结果: y1 + product
return y1.add(product);
}
} }