using OpenCvSharp; namespace SimulationCommon; public class WeatherResponse { public Wind Wind { get; set; } } public class Wind { public double Speed { get; set; } public double Deg { get; set; } } public class CurrentResponse { public Current Current { get; set; } } public class Current { public double Speed { get; set; } public double Direction { get; set; } } public class NCread { //各数组来源文件'Text_readNC.cs';时间范围:2024-06-04T00:00:00 ... 2024-06-04T23:00:00; //地点范围:落水点为中心100公里 public float[] longitudeArray = new float[10];//经度一维数组来源自文件'Text_readNC.cs' public float[] latitudeArray = new float[7];//纬度一维数组来源自文件'Text_readNC.cs' public float[][][] u10Array ;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs' public float[][][] v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs' public float[][][] p140208Array;//海洋上空的自由对流速度三维数组来源自文件'Text_readNC.cs' public float[][][] mwdArray;//平均波向(单位:度;0度表示北方,90度表示东方)三维数组来源自文件'Text_readNC.cs' } public class SeaSJ { // 生成符合正态分布的随机数 public static double NormalDistributionRandom(double mu, double sigma) { Random rand = new Random(); 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) } // 交付类方法 public static List GetDrift(NCread nCread,double[] initialPosition, double dt, double totalTime) { // run 获取轨迹的函数 // initialPosition --> 初始位置; dt --> 时间步长; totalTime --> 总时长 List trajectory = CalculateDriftTrajectory(nCread,initialPosition, dt, totalTime); return trajectory; } public static List CalculateDriftTrajectory(NCread nCread,double[] initialPosition, double dt, double totalTime) { int timeSteps = (int)(totalTime / dt); List trajectory = new List(); trajectory.Add(new double[] { initialPosition[0], initialPosition[1] }); for (int t = 1; t < timeSteps; t++) { double[] currentPos = trajectory[t - 1]; // 动态获取当前位置的风力和洋流数据 double[] windVelocity = GetWindVelocityFromAPI(nCread,currentPos[0], currentPos[1], t); double[] currentVelocity = GetCurrentVelocityFromAPI(nCread,currentPos[0], currentPos[1], t); // 计算漂移速度 double[] driftVelocity = { currentVelocity[0] + windVelocity[0], currentVelocity[1] + windVelocity[1] }; // 更新位置(假设漂移速度是海里每小时,需要转换成经纬度的变化量) double[] newPosition = { currentPos[0] + (driftVelocity[0] * dt / 60.0), // 纬度变化量 currentPos[1] + (driftVelocity[1] * dt / 60.0) // 经度变化量 }; trajectory.Add(newPosition); } return trajectory; } public static double[] GetWindVelocityFromAPI(NCread windNCread,double latitude, double longitude, int time) { float[] longitudeArray = windNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs' float[] latitudeArray = windNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs' float[][][] u10Array = windNCread.u10Array;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs' float[][][] v10Array = windNCread.v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs' int longitudeNum = 0; int latitudeNum = 0; //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等) //经度连续化 for (int i = 0; i < 10; i++) { if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1]) { longitude = longitudeArray[i]; longitudeNum = i; } } //纬度连续化 for (int i = 0; i < 7; i++) { if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1]) { latitude = latitudeArray[i]; latitudeNum = i; } } double windX = (double)u10Array[time][latitudeNum][longitudeNum]; double windY = (double)v10Array[time][latitudeNum][ longitudeNum]; return new double[] { windX, windY }; } public static double[] GetCurrentVelocityFromAPI(NCread windNCread,double latitude, double longitude, int time) { float[] longitudeArray = windNCread.longitudeArray;//经度一维数组来源自文件'Text_readNC.cs' float[] latitudeArray = windNCread.latitudeArray;//纬度一维数组来源自文件'Text_readNC.cs' float[][][] u10Array = windNCread.u10Array;//风的10米U(向东)分量三维数组来源自文件'Text_readNC.cs' float[][][] v10Array = windNCread.v10Array;//风的10米V(向北)分量三维数组来源自文件'Text_readNC.cs' int longitudeNum = 0; int latitudeNum = 0; //定义NC文件中读取不到的坐标点海洋数据信息(后续可采用插值法等) //经度连续化 for (int i = 0; i < 10; i++) { if (longitude >= longitudeArray[i] && longitude < longitudeArray[i + 1]) { longitude = longitudeArray[i]; longitudeNum = i; } } //纬度连续化 for (int i = 0; i < 7; i++) { if (latitude >= latitudeArray[i] && latitude < latitudeArray[i + 1]) { latitude = latitudeArray[i]; latitudeNum = i; } } double windX = (double)u10Array[time][ latitudeNum][longitudeNum]; double windY = (double)v10Array[time][latitudeNum][ longitudeNum]; return new double[] { windX, windY }; } // 交付部分方法代码 public static List getminEnclosingRect(List latLonList) { // 转换经纬度为墨卡托投影坐标,并添加到点集合 List pointList = new List(); foreach (var latLon in latLonList) { double x = Rectangular_Area_Search_Function.MokatuoLat(latLon[0]); double y = Rectangular_Area_Search_Function.MokatuoLon(latLon[1]); pointList.Add(new Point2f((float)x, (float)y)); } // 获取凸包 Point2f[] convexHull = Rectangular_Area_Search_Function.GetConvexHull(pointList); // 计算最小包围矩形 List minEnclosingRect = Rectangular_Area_Search_Function.MinEnclosingRectangle(convexHull); // 最小包围矩形顶点经纬度坐标 List startPoint = new List(); foreach (var minEnclosingRectPoint in minEnclosingRect) { double lat = Rectangular_Area_Search_Function.RMokatuoLat(minEnclosingRectPoint[0]); double lon = Rectangular_Area_Search_Function.RMokatuoLon(minEnclosingRectPoint[1]); startPoint.Add(new double[] { lat, lon }); } return startPoint; } }