namespace SimulationCommon;

public class tempNCread
{
    public float[] longitudeArray = new float[10];//经度一维数组来源自文件'Text_readNC.cs'
    public float[] latitudeArray = new float[7];//纬度一维数组来源自文件'Text_readNC.cs'

    public float[][][] tempArray ;//温度三维数组来源自文件'temp_readNC.cs'

}
public class SurvivalTimeModel
{
    //得到在某经纬度、任务运行时间下的落水人员幸存时间
    public static double SurvivalTime(tempNCread tempNCread, double latitude, double longitude, double time, int times, int latitudes, int longitudes, int days, int hour)
        //time表示任务执行时间,单位:秒,后续可以转换单位
    {
        int latitudeNum = 0;
        int longitudeNum = 0;
        int timeNum = 0;

        float[] longitudeArray = tempNCread.longitudeArray; //经度一维数组来源自文件'Text_readNC.cs'
        float[] latitudeArray = tempNCread.latitudeArray; //纬度一维数组来源自文件'Text_readNC.cs'
        float[][][] tempArray = tempNCread.tempArray;

        //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等)
        //经度连续化
        for (int i = 0; i < longitudes - 1; i++)
        {
            if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1])
            {
                longitude = longitudeArray[i];
                longitudeNum = i;
            }
        }

        //纬度连续化
        for (int i = 0; i < latitudes - 1; i++)
        {
            if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1])
            {
                latitude = latitudeArray[i];
                latitudeNum = i;
            }
        }

        //时间连续化
        for (int i = 0; i < times - 1; i++)
        {
            if (time >= (i * 3600) && time < ((i + 1) * 3600))
            {
                timeNum = i;
            }
        }
        timeNum += (days - 1) * 24 + hour;
        double temp = (double)tempArray[timeNum][ latitudeNum][ longitudeNum]; //得到该坐标和时间下的温度

        double time1 = 1.2860 * Math.Exp(0.1604 * temp);
        double time2 = 1.0201 * Math.Exp(0.1277 * temp);
        double time3 = 0.5892 * Math.Exp(0.1246 * temp);

        // 生成符合正态分布的随机样本
        Random rand = new Random();
        double mu = (time1 + time3) / 2; // 平均值
        double sigma = (time3 - time1) / 6; // 标准差(假设曲线1和曲线3的幸存时间分布接近对称,因此标准差为幅度的六分之一)
        double survivalTime = NormalDistributionRandom(rand, mu, sigma); //计算该温度下的幸存时间

        return survivalTime;
    }

    // 生成符合正态分布的随机数
    public static double NormalDistributionRandom(Random rand, double mu, double sigma)
    {
        double u1 = 1.0 - rand.NextDouble(); // uniform(0,1] random doubles
        double u2 = 1.0 - rand.NextDouble();
        double normalRandom = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2); // random normal(0,1)
        return mu + sigma * normalRandom; // random normal(mean,stdDev^2)
    }
}