AABB与球的相交检测、AABB到一个点最近的点

AABB与球的相交检测、AABB到一个点最近的点

如果一个AABB与球相交,则AABB内至少有一个点到球心的距离小于等于球的半径。
只需要找到AABB内到球心最近的一个点,判断点到球心的距离与半径长度关系。

如果球心在 AABB 内,则AABB到球心距离最近的点就是球心所在的点

如果球心在 AABB 外,则AABB到球心距离最近的点一定在AABB的一个表面上

我们假设,球心坐标(X, Y, Z) 就是 AABB内到球最近的一个点
因为AABB内所有的点都在(min, max)范围内

如果 X < AABB.min.x 令 X = AABB.min.x
如果 X > AABB.max.x 令 X = AABB.max.x

同理 Y、Z也这样处理,最终的 坐标 (X,Y,Z) 就是 AABB上的点到球心最近的点

代码如下

public class AABBSphereCollision
{
    /// <summary>
    /// AABB与球相交检测
    /// </summary>
    /// <param name="aabb">AABB数据</param>
    /// <param name="spherePos">球中心坐标</param>
    /// <param name="radius">球半径</param>
    /// <returns></returns>
    public static bool IsCollision(AABB aabb, Vector3 spherePos, float radius)
    {
        Vector3 nearestPoint = AABBNearestPointToPoint(aabb, spherePos);
        float distance = Vector3.Distance(nearestPoint, spherePos);
        return distance <= radius;
    }

    /// <summary>
    /// AABB 内到所有点中到一个指定点最近的点坐标
    /// </summary>
    /// <param name="aabb"></param>
    /// <param name="spherePos"></param>
    /// <returns></returns>
    public static Vector3 AABBNearestPointToPoint(AABB aabb, Vector3 spherePos)
    {
        float x = spherePos.x;
        x = x > aabb.max.x ? aabb.max.x : x;
        x = x < aabb.min.x ? aabb.min.x : x;

        float y = spherePos.y;
        y = y > aabb.max.y ? aabb.max.y : y;
        y = y < aabb.min.y ? aabb.min.y : y;

        float z = spherePos.z;
        z = z > aabb.max.z ? aabb.max.z : z;
        z = z < aabb.min.z ? aabb.min.z : z;

        return new Vector3(x, y, z);
    }
}

测试效果如下
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值