用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);
|
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
|
var frame = new AnimationFrame
|
||||||
{
|
{
|
||||||
@ -600,16 +597,9 @@ namespace NavisworksTransport.Core.Animation
|
|||||||
var colliderBox = collider.BoundingBox();
|
var colliderBox = collider.BoundingBox();
|
||||||
|
|
||||||
// 🔥 调试日志:输出包围盒信息
|
// 🔥 调试日志:输出包围盒信息
|
||||||
bool intersects = BoundingBoxGeometryUtils.BoundingBoxesIntersectWithTolerance(virtualBoundingBox, colliderBox, _detectionGap);
|
// 使用改进的精确距离检测方法(先检查相交,再计算精确距离)
|
||||||
if (intersects)
|
double preciseDistance = BoundingBoxGeometryUtils.CalculatePreciseDistance(virtualBoundingBox, colliderBox);
|
||||||
{
|
bool intersects = preciseDistance <= _detectionGap;
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intersects)
|
if (intersects)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -177,6 +177,62 @@ namespace NavisworksTransport.Utils
|
|||||||
box1.Min.Z <= box2.Max.Z && box1.Max.Z >= box2.Min.Z;
|
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>
|
/// <summary>
|
||||||
/// 获取包围盒的中心点
|
/// 获取包围盒的中心点
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user