using System; using System.Collections.Generic; using System.Linq; namespace 头罩视野.Services { public static class GetArea { // 灯条参数 public const int totalLights = 81; // 每条灯条81个灯 public static double verticalAngleStep = 90.0 / (totalLights - 1); // 1.125° public static double CalculateBottomViewAngle(int[] lightData, List<(int m, int n)> lightPositions) { int bottomLampCount = 0; for (int i = 0; i < lightData.Length && i < lightPositions.Count; i++) { if (lightPositions[i].n == 1 && lightData[i] == 1) bottomLampCount++; } return (double)bottomLampCount / 81 * 90.0; } /// /// 根据径向灯条0/1数据计算边界角度(极角,度) /// /// 从上到下的灯条状态,索引0=顶部0°,索引80=底部90° public static double ComputeBoundaryAngle(int[] lightStates) { if (lightStates == null || lightStates.Length != totalLights) return 0; int firstZero = -1; for (int i = 0; i < totalLights; i++) { if (lightStates[i] == 0) { firstZero = i; break; } } if (firstZero == -1) return 90.0; // 全亮 if (firstZero == 0) return 0.0; // 顶部即被遮 // 边界角度 = 上一个灯条的结束角 = (firstZero) * verticalAngleStep return firstZero * verticalAngleStep; } /// /// 极坐标梯形法积分面积(半径数组单位:度,步长单位:度) /// public static double IntegrateArea(double[] radiiDeg, double deltaThetaDeg) { if (radiiDeg == null || radiiDeg.Length < 2) return 0; double deltaRad = deltaThetaDeg * Math.PI / 180.0; double sum = 0.0; for (int i = 0; i < radiiDeg.Length - 1; i++) { double r1 = radiiDeg[i]; double r2 = radiiDeg[i + 1]; double avgRSq = (r1 * r1 + r2 * r2) / 2.0; sum += avgRSq * deltaRad; } return 0.5 * sum; } /// /// 根据左右眼边界半径数组,计算总视野(并集)和双目视野(交集)面积 /// public static (double totalArea, double biArea) ComputeTotalAndBinocularArea(double[] leftRadii, double[] rightRadii, double deltaThetaDeg) { int len = Math.Min(leftRadii.Length, rightRadii.Length); double[] totalRadii = new double[len]; double[] biRadii = new double[len]; for (int i = 0; i < len; i++) { totalRadii[i] = Math.Max(leftRadii[i], rightRadii[i]); biRadii[i] = Math.Min(leftRadii[i], rightRadii[i]); } double totalArea = IntegrateArea(totalRadii, deltaThetaDeg); double biArea = IntegrateArea(biRadii, deltaThetaDeg); return (totalArea, biArea); } /// /// 保存率计算公式(带γ校正) /// public static double ComputePreservation(double measuredArea, double standardArea, double gamma) { if (standardArea <= 0) return 0; return gamma * (measuredArea / standardArea) * 100.0; } /// /// 根据面积比获取γ校正系数(GB 2890-2022 图D.4) /// public static double GetGammaByRatio(double ratio) { double[] x = { 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 }; double[] y = { 1.22, 1.18, 1.14, 1.10, 1.06, 1.03, 1.02, 1.01, 1.00 }; if (ratio <= x[0]) return y[0]; if (ratio >= x.Last()) return y.Last(); for (int i = 0; i < x.Length - 1; i++) { if (ratio >= x[i] && ratio <= x[i + 1]) { double t = (ratio - x[i]) / (x[i + 1] - x[i]); return y[i] + t * (y[i + 1] - y[i]); } } return 1.0; } } }