NavisworksTransport/src/Utils/CornerTurnCheckHelper.cs

59 lines
2.0 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;
namespace NavisworksTransport.Utils
{
public static class CornerTurnCheckHelper
{
/// <summary>
/// 基于标准转角通过公式L(θ) = (C₁-W·cosθ)/sinθ + (C₂-W·sinθ)/cosθ
/// 在 θ ∈ (0, π/2) 上搜索最大可通过长度。
/// </summary>
public static bool CanPass(double length, double width, double entryWidth, double exitWidth,
out double margin, out double maxLength)
{
margin = 0;
maxLength = 0;
if (length <= 0 || width <= 0 || entryWidth <= 0 || exitWidth <= 0)
return false;
if (width > entryWidth || width > exitWidth)
return false;
maxLength = FindRequiredLength(width, entryWidth, exitWidth);
margin = maxLength - length;
return length <= maxLength;
}
/// <summary> 给定角度 θ,计算该角度下能通过的最大模块长度 </summary>
private static double L(double theta, double width, double c1, double c2)
{
var sin = Math.Sin(theta);
var cos = Math.Cos(theta);
return (c1 - width * cos) / sin + (c2 - width * sin) / cos;
}
/// <summary> 三分法搜索 θ ∈ (0, π/2) 上 L(θ) 的最小值(即最大可通过长度) </summary>
private static double FindRequiredLength(double width, double c1, double c2)
{
double lo = 1e-6;
double hi = Math.PI / 2 - 1e-6;
// 三分搜索
for (int i = 0; i < 80; i++)
{
var m1 = lo + (hi - lo) / 3;
var m2 = hi - (hi - lo) / 3;
var f1 = L(m1, width, c1, c2);
var f2 = L(m2, width, c1, c2);
if (f1 < f2)
hi = m2;
else
lo = m1;
}
return L((lo + hi) / 2, width, c1, c2);
}
}
}