//仿真时间单独计时
using System.IO;
public class Fire
{
public class Aircraft
{
public string f_model { get; set; } //机型
public string f_type { get; set; } //飞机种类
public double f_zsl { get; set; } //载水量;前端给出
public double f_mhd { get; set; } //灭火弹数量;前端给出
public double f_mhdarea { get; set; } //单个灭火弹喷洒面积;前端给出
}
public class FireGrid
{
public double Time;
public double FireGrids;
public double FiredGrids;
}
//随机数X:0到1
public static double GenerateRandomNumber()
{
Random random = new Random();
double randomNumber = random.NextDouble();
return randomNumber;
}
//小型直升机洒水概率(IP*POS)
public static double SAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.72 + 0.01 * Math.Exp(exponent);
double result = POS * 1;
return POS;
}
//中型直升机洒水概率
public static double MAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.8 + 0.1 * Math.Exp(exponent);
double result = POS * 0.93;
return POS;
}
//大型直升机
public static double LAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.62 + 0.2 * Math.Exp(exponent);
double result = POS * 0.87;
return POS;
}
//多引擎水陆两栖飞机
public static double MultiAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.72 + 0.16 * Math.Exp(exponent);
double result = POS * 1;
return POS;
}
//单引擎水陆两栖飞机
public static double AmAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.88 + 0.02 * Math.Exp(exponent);
double result = POS * 1;
return POS;
}
//单引擎灭火飞机
public static double SEAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.53 + 0.27 * Math.Exp(exponent);
double result = POS * 0.8;
return POS;
}
//大型灭火飞机
public static double LFAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.53 + 0.27 * Math.Exp(exponent);
double result = POS * 0.74;
return POS;
}
//超大型灭火飞机
public static double ULFAirProbability(double sigma = 1)
{
double x = GenerateRandomNumber();
double exponent = -Math.Pow(x, 2) / (2 * Math.Pow(sigma, 2));
double POS = 0.53 + 0.27 * Math.Exp(exponent);
double result = POS * 0.76;
return POS;
}
//灭火弹有效洒水面积
public static double grenadeArea(double f_mhd, double f_mhdarea)
{
double _grenadeArea = f_mhd * f_mhdarea * 0.9;
return _grenadeArea;
}
//吊桶水箱有效洒水面积
public static double SprinklerArea(string type, double f_zsl, double sigma = 1)
{
double _f_zsl = 0;
double _sprinklerArea = 0;
switch (type)
{
case "大型直升机":
double probability1 = LAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability1;
_sprinklerArea = _f_zsl / 1.8;
break;
case "中型直升机":
double probability2 = MAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability2;
_sprinklerArea = _f_zsl / 1.8;
break;
case "小型直升机":
double probability3 = SAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability3;
_sprinklerArea = _f_zsl / 1.8;
break;
case "多引擎水陆两栖飞机":
double probability4 = MultiAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability4;
_sprinklerArea = _f_zsl / 1.8;
break;
case "单引擎水陆两栖飞机":
double probability5 = AmAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability5;
_sprinklerArea = _f_zsl / 1.8;
break;
case "单引擎灭火飞机":
double probability6 = SEAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability6;
_sprinklerArea = _f_zsl / 1.8;
break;
case "大型灭火飞机":
double probability7 = LFAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability7;
_sprinklerArea = _f_zsl / 1.8;
break;
case "超大型灭火飞机":
double probability8 = ULFAirProbability(sigma) * AirdropAccuracy.GetIpForType(type);
_f_zsl = f_zsl * probability8;
_sprinklerArea = _f_zsl / 1.8;
break;
default:
break;
}
return _sprinklerArea;
}
//地面人员灭火有效面积
//任务开始后,每一批次人员相当于一架飞机,每半小时灭火面积相当于一次洒水面积
//地面部署人员、机降人员到达时间、介入人数(王子涵传入)
public static double groundPersonnelWater(int num)
{
// 灭火火线长度
double PL;
// 10分钟洒水火线长度
PL = 0.16 * num * 55;
// 10分钟灭火面积
double result = PL * 5;
return result;
}
public class CountArea
{
public double burncount { get; set; } //火焰蔓延网格数
public double burnarea { get; set; } //火焰蔓延面积
}
///
/// 火焰蔓延计算方法,第一次洒水前是仿真时间
///
/// 风速
/// 坡度//与风向相关
/// 植被类型 //1~11
/// 天气温度 //前端给出
/// 飞机仿真时间/s
/// 上一次洒水后的面积
/// 本次洒水时间
/// 上一次洒水时间
/// 初始输入火场面积
///
///"1 针叶林","2 针阔叶混交林","3 阔叶林", "4 灌丛", "5 荒漠","6 草原", "7 草丛","8 草甸","9 沼泽","10 高山植被","11 栽培植被","0 无植被"
///
public class VegetationCalculator
{
// 定义一个字典来存储每个 vegetation 数值对应的 KS 和 KW 计算公式
private static readonly Dictionary> vegetationFormulas =
new Dictionary>()
{
{ 1, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.8*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 2, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.9*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 3, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 4, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.5*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 5, (radians, wind) => (0,0) },
{ 6, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.3*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 7, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.3*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 8, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.3*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 9, (radians, wind) => (0,0) },
{ 10, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.85*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 11, (radians, wind) => (0.1127 * Math.Pow(Math.Tan(radians), 2), 0.4*0.422 * Math.Pow((3.284 * wind), 0.381)) },
{ 0, (radians, wind) => (0,0) }
};
public static (double KS, double KW) Calculate(int vegetation, double radians, double wind)
{
if (vegetationFormulas.TryGetValue(vegetation, out var formula))
{
return formula(radians, wind);
}
else
{
throw new ArgumentException("Invalid vegetation value");
}
}
}
//输入初始火场面积,计算已蔓延时间
public static double InitialburnTime(double wind, double slope, int vegetation, double Weather_T, double InitialArea)
{
double count = InitialArea / 400;
double radians = slope * (Math.PI / 180); // 将角度转换为弧度
// 根据 vegetation 计算 KS 和 KW
var (KS, KW) = VegetationCalculator.Calculate(vegetation, radians, wind);
double time = (count / (0.04 * Weather_T * KS * KW) + 9.06) / 0.3052;
return time ;
}
public static CountArea burnCalculate(double wind, double slope, int vegetation, double Weather_T, double time, double burnarea, double tn, double tn_1, double InitialArea)
{
double x = GenerateRandomNumber();
if (wind == 0) wind = 1;
if (slope < 16) slope = 16;
if (slope > 45) slope = 45;
if (burnarea == 0)
{
if (InitialArea > 0) time = InitialburnTime(wind, slope, vegetation, Weather_T, InitialArea) + time;
}
else
{
//上一次洒水后面积计算得到的时间,加上两次洒水间隔
time = InitialburnTime(wind, slope, vegetation, Weather_T, burnarea) + (tn - tn_1);
}
double radians = slope * (Math.PI / 180); // 将角度转换为弧度
var (KS, KW) = VegetationCalculator.Calculate(vegetation, radians, wind);
double count = 0.04 * Weather_T * KS * KW * (0.3052 * time - 9.06);
double area = count * 400;
return new CountArea { burncount = count, burnarea = area };
}
///
/// 燃尽面积计算输出公式
///
/// 风速
/// 坡度//与风向相关
/// 植被类型 //1~11
/// 初始天气温度 //前端给出
/// 从开始到结束的天气温度均值 //数据库读取
/// 任务耗时
/// 初始输入火场面积
///
/// "1 针叶林","2 针阔叶混交林","3 阔叶林", "4 灌丛", "5 荒漠","6 草原", "7 草丛","8 草甸","9 沼泽","10 高山植被","11 栽培植被","0 无植被"
public class VegetationCalculatored
{
// 定义一个字典来存储每个 vegetation 数值对应的 KS 和 KW 计算公式
private static readonly Dictionary> vegetationFormulas =
new Dictionary>()
{
{ 1, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 0.8*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 2, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 0.9*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 3, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 4, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 0.5*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 5, (radians, wind) => ((0,0)) },
{ 6, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 1.5*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 7, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 1.5*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 8, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 1.5*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 9, (radians, wind) => (0,0) },
{ 10, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 0.85*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 11, (radians, wind) => (0.8*0.0648 * Math.Pow(Math.Tan(radians), 2), 1.3*0.8*0.438 * Math.Pow((3.284 * wind), 0.381)) },
{ 0, (radians, wind) => (0,0) }
};
public static (double KS, double KW) Calculate(int vegetation, double radians, double wind)
{
if (vegetationFormulas.TryGetValue(vegetation, out var formula))
{
return formula(radians, wind);
}
else
{
throw new ArgumentException("Invalid vegetation value");
}
}
}
//每小时都更新天气的火场燃尽面积
public static CountArea burnedCalculate(double wind, double slope, int vegetation, double Weather_T_ave, double Weather_T1, double time, double InitialArea)
{
double x = GenerateRandomNumber();
if (wind == 0) wind = 1;
if (slope < 16) slope = 16;
if (InitialArea > 0) time += InitialburnTime(wind, slope, vegetation, Weather_T1, InitialArea);
double radians = slope * (Math.PI / 180); // 将角度转换为弧度
// 根据 vegetation 计算 KS 和 KW
var (KS, KW) = VegetationCalculatored.Calculate(vegetation, radians, wind);
double count = 0.04 * Weather_T_ave * KS * KW * (2.5458 * time - 2999);
double area = (count) * 400;
return new CountArea { burncount = count, burnarea = area };
}
///
/// 过火面积
///
/// 风速
/// 破度
/// 植被类型
/// 平均温度值
/// 初始温度值
/// 时间
/// 初始面积
/// 累计洒水面积
///
public static double fireCalculate(double wind, double slope, int vegetation, double Weather_T_ave, double Weather_T1, double time, double InitialArea, double waterArea)
{
double FireArea = 0;
CountArea burnedArea = burnedCalculate(wind, slope, vegetation, Weather_T_ave, Weather_T1, time, InitialArea);
FireArea = burnedArea.burnarea + waterArea;
return FireArea;
}
}