用API精确计算包围盒的距离,解决多检的问题
This commit is contained in:
parent
cbc63809f0
commit
f02e5cfc28
@ -539,9 +539,6 @@ namespace NavisworksTransport.Core.Animation
|
||||
|
||||
double yawRadians = ComputeYawOnPath(i, allSampledPoints, edgeIndex, edgeProgress);
|
||||
|
||||
// 🔥 调试日志:输出framePosition
|
||||
LogManager.Debug($"[调试] 帧{i}: framePosition=({framePosition.X:F2},{framePosition.Y:F2},{framePosition.Z:F2})");
|
||||
|
||||
// 创建帧并检测碰撞
|
||||
var frame = new AnimationFrame
|
||||
{
|
||||
@ -600,16 +597,9 @@ namespace NavisworksTransport.Core.Animation
|
||||
var colliderBox = collider.BoundingBox();
|
||||
|
||||
// 🔥 调试日志:输出包围盒信息
|
||||
bool intersects = BoundingBoxGeometryUtils.BoundingBoxesIntersectWithTolerance(virtualBoundingBox, colliderBox, _detectionGap);
|
||||
if (intersects)
|
||||
{
|
||||
double distanceX = Math.Max(0, Math.Max(virtualBoundingBox.Min.X - colliderBox.Max.X, colliderBox.Min.X - virtualBoundingBox.Max.X));
|
||||
double distanceY = Math.Max(0, Math.Max(virtualBoundingBox.Min.Y - colliderBox.Max.Y, colliderBox.Min.Y - virtualBoundingBox.Max.Y));
|
||||
double distanceZ = Math.Max(0, Math.Max(virtualBoundingBox.Min.Z - colliderBox.Max.Z, colliderBox.Min.Z - virtualBoundingBox.Max.Z));
|
||||
double minDistance = Math.Max(distanceX, Math.Max(distanceY, distanceZ));
|
||||
|
||||
LogManager.Debug($"[碰撞检测] 帧{i}: 车辆包围盒=[({virtualBoundingBox.Min.X:F2},{virtualBoundingBox.Min.Y:F2},{virtualBoundingBox.Min.Z:F2})-({virtualBoundingBox.Max.X:F2},{virtualBoundingBox.Max.Y:F2},{virtualBoundingBox.Max.Z:F2})], 物体={collider.DisplayName}, 包围盒=[({colliderBox.Min.X:F2},{colliderBox.Min.Y:F2},{colliderBox.Min.Z:F2})-({colliderBox.Max.X:F2},{colliderBox.Max.Y:F2},{colliderBox.Max.Z:F2})], 最小距离={minDistance:F3}m, 检测间隙={_detectionGap:F3}m");
|
||||
}
|
||||
// 使用改进的精确距离检测方法(先检查相交,再计算精确距离)
|
||||
double preciseDistance = BoundingBoxGeometryUtils.CalculatePreciseDistance(virtualBoundingBox, colliderBox);
|
||||
bool intersects = preciseDistance <= _detectionGap;
|
||||
|
||||
if (intersects)
|
||||
{
|
||||
|
||||
@ -177,6 +177,62 @@ namespace NavisworksTransport.Utils
|
||||
box1.Min.Z <= box2.Max.Z && box1.Max.Z >= box2.Min.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用ClosestPoint方法计算两个包围盒之间的精确距离
|
||||
/// 这种方法比简单的包围盒相交检测更精确,可以避免AABB扩大导致的误报
|
||||
/// </summary>
|
||||
/// <param name="box1">第一个包围盒</param>
|
||||
/// <param name="box2">第二个包围盒</param>
|
||||
/// <returns>两个包围盒之间的精确距离</returns>
|
||||
public static double CalculatePreciseDistance(BoundingBox3D box1, BoundingBox3D box2)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 先检查包围盒是否相交
|
||||
bool intersects = box1.Intersects(box2);
|
||||
|
||||
if (intersects)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// 如果不相交,使用ClosestPoint方法计算精确距离
|
||||
// 计算box1上距离box2最近的点
|
||||
Point3D closestPointOnBox1 = box1.ClosestPoint(box2.Center);
|
||||
|
||||
// 计算box2上距离closestPointOnBox1最近的点
|
||||
Point3D closestPointOnBox2 = box2.ClosestPoint(closestPointOnBox1);
|
||||
|
||||
// 计算两个最近点之间的距离
|
||||
double dx = closestPointOnBox1.X - closestPointOnBox2.X;
|
||||
double dy = closestPointOnBox1.Y - closestPointOnBox2.Y;
|
||||
double dz = closestPointOnBox1.Z - closestPointOnBox2.Z;
|
||||
|
||||
double distance = Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
return distance;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// API调用失败,记录错误并抛出异常
|
||||
LogManager.Error($"[CalculatePreciseDistance] API调用失败: {ex.Message}");
|
||||
throw new InvalidOperationException($"CalculatePreciseDistance API调用失败: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用ClosestPoint方法检查两个包围盒是否在容差范围内相交
|
||||
/// 这种方法比简单的包围盒相交检测更精确,可以避免AABB扩大导致的误报
|
||||
/// </summary>
|
||||
/// <param name="box1">第一个包围盒</param>
|
||||
/// <param name="box2">第二个包围盒</param>
|
||||
/// <param name="tolerance">容差值</param>
|
||||
/// <returns>如果包围盒在容差范围内相交则返回true</returns>
|
||||
public static bool BoundingBoxesIntersectWithTolerancePrecise(BoundingBox3D box1, BoundingBox3D box2, double tolerance)
|
||||
{
|
||||
double preciseDistance = CalculatePreciseDistance(box1, box2);
|
||||
return preciseDistance <= tolerance;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取包围盒的中心点
|
||||
|
||||
Loading…
Reference in New Issue
Block a user