Files
hoodFieldOfView/头罩视野slove/头罩视野/Services/GetArea.cs
2026-05-25 13:56:11 +08:00

111 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
/// <summary>
/// 根据径向灯条0/1数据计算边界角度极角
/// </summary>
/// <param name="lightStates">从上到下的灯条状态索引0=顶部0°索引80=底部90°</param>
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;
}
/// <summary>
/// 极坐标梯形法积分面积(半径数组单位:度,步长单位:度)
/// </summary>
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;
}
/// <summary>
/// 根据左右眼边界半径数组,计算总视野(并集)和双目视野(交集)面积
/// </summary>
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);
}
/// <summary>
/// 保存率计算公式(带γ校正)
/// </summary>
public static double ComputePreservation(double measuredArea, double standardArea, double gamma)
{
if (standardArea <= 0) return 0;
return gamma * (measuredArea / standardArea) * 100.0;
}
/// <summary>
/// 根据面积比获取γ校正系数GB 2890-2022 图D.4
/// </summary>
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;
}
}
}