Unity3d数学公式之 OBB vs OBB

数学公式相信是一些开发者头疼的一个问题 尤其是数学基础不太好的同学 开发的时候能找到一个正确的又好用的现成的代码断是一件很happy的事情 这里我就将我之前项目里面实际使用过的代码段直接放出来 有需要的朋友自己拿走吧

//两个OBB是否相交
    public static bool IsOBBIntersectionWithOBB(ref Vector2 blA, ref Vector2 tlA, ref Vector2 trA, ref Vector2 brA,
        ref Vector2 blB, ref Vector2 tlB, ref Vector2 trB, ref Vector2 brB)
    {
        Vector2 axisA1 = trA - tlA;
        if (!IsOBBOverlapedOnAxisX(ref axisA1, ref blA, ref tlA, ref trA, ref brA, ref blB, ref tlB, ref trB, ref brB)) return false;
        Vector2 axisA2 = trA - brA;
        if (!IsOBBOverlapedOnAxisY(ref axisA2, ref blA, ref tlA, ref trA, ref brA, ref blB, ref tlB, ref trB, ref brB)) return false;
        Vector2 axisB1 = trB - tlB;
        if (!IsOBBOverlapedOnAxisX(ref axisB1, ref blA, ref tlA, ref trA, ref brA, ref blB, ref tlB, ref trB, ref brB)) return false;
        Vector2 axisB2 = trB - brB;
        if (!IsOBBOverlapedOnAxisY(ref axisB2, ref blA, ref tlA, ref trA, ref brA, ref blB, ref tlB, ref trB, ref brB)) return false;
        return true;
    }
    //两个OBB是否是某个方向上投影有重合
    private static bool IsOBBOverlapedOnAxisX(ref Vector2 axis, ref Vector2 blA, ref Vector2 tlA, ref Vector2 trA, ref Vector2 brA,
        ref Vector2 blB, ref Vector2 tlB, ref Vector2 trB, ref Vector2 brB)
    {
        float axisSqrLen = Vector2.Dot(axis, axis);
        if (IsApproximately(axisSqrLen, 0f)) return true;
        Vector2 scaleDir = axis / axisSqrLen;

        Vector2 axis_bla = Vector2.Dot(blA, axis) * scaleDir;
        Vector2 axis_tla = Vector2.Dot(tlA, axis) * scaleDir;
        Vector2 axis_tra = Vector2.Dot(trA, axis) * scaleDir;
        Vector2 axis_bra = Vector2.Dot(brA, axis) * scaleDir;

        Vector2 axis_blb = Vector2.Dot(blB, axis) * scaleDir;
        Vector2 axis_tlb = Vector2.Dot(tlB, axis) * scaleDir;
        Vector2 axis_trb = Vector2.Dot(trB, axis) * scaleDir;
        Vector2 axis_brb = Vector2.Dot(brB, axis) * scaleDir;

        float minAX = Mathf.Min(axis_bla.x, axis_tla.x);
        minAX = Mathf.Min(axis_tra.x, minAX);
        minAX = Mathf.Min(axis_bra.x, minAX);
        float maxBX = Mathf.Max(axis_blb.x, axis_tlb.x);
        maxBX = Mathf.Max(axis_trb.x, maxBX);
        maxBX = Mathf.Max(axis_brb.x, maxBX);
        if (minAX > maxBX) return false;

        float maxAX = Mathf.Max(axis_bla.x, axis_tla.x);
        maxAX = Mathf.Max(axis_tra.x, maxAX);
        maxAX = Mathf.Max(axis_bra.x, maxAX);
        float minBX = Mathf.Min(axis_blb.x, axis_tlb.x);
        minBX = Mathf.Min(axis_trb.x, minBX);
        minBX = Mathf.Min(axis_brb.x, minBX);
        if (maxAX < minBX) return false;
        return true;
    }
    private static bool IsOBBOverlapedOnAxisY(ref Vector2 axis, ref Vector2 blA, ref Vector2 tlA, ref Vector2 trA, ref Vector2 brA,
       ref Vector2 blB, ref Vector2 tlB, ref Vector2 trB, ref Vector2 brB)
    {
        float axisSqrLen = Vector2.Dot(axis, axis);
        if (IsApproximately(axisSqrLen, 0f)) return true;
        Vector2 scaleDir = axis / axisSqrLen;

        Vector2 axis_bla = Vector2.Dot(blA, axis) * scaleDir;
        Vector2 axis_tla = Vector2.Dot(tlA, axis) * scaleDir;
        Vector2 axis_tra = Vector2.Dot(trA, axis) * scaleDir;
        Vector2 axis_bra = Vector2.Dot(brA, axis) * scaleDir;

        Vector2 axis_blb = Vector2.Dot(blB, axis) * scaleDir;
        Vector2 axis_tlb = Vector2.Dot(tlB, axis) * scaleDir;
        Vector2 axis_trb = Vector2.Dot(trB, axis) * scaleDir;
        Vector2 axis_brb = Vector2.Dot(brB, axis) * scaleDir;

        float minAY = Mathf.Min(axis_bla.y, axis_tla.y);
        minAY = Mathf.Min(axis_tra.y, minAY);
        minAY = Mathf.Min(axis_bra.y, minAY);
        float maxBY = Mathf.Max(axis_blb.y, axis_tlb.y);
        maxBY = Mathf.Max(axis_trb.y, maxBY);
        maxBY = Mathf.Max(axis_brb.y, maxBY);
        if (minAY > maxBY) return false;

        float maxAY = Mathf.Max(axis_bla.y, axis_tla.y);
        maxAY = Mathf.Max(axis_tra.y, maxAY);
        maxAY = Mathf.Max(axis_bra.y, maxAY);
        float minBY = Mathf.Min(axis_blb.y, axis_tlb.y);
        minBY = Mathf.Min(axis_trb.y, minBY);
        minBY = Mathf.Min(axis_brb.y, minBY);       
        if (maxAY < minBY) return false;
        return true;
    }

//计算两个数字是否接近相等
    public static bool IsApproximately(double a, double b)
    {
        return IsApproximately(a, b, minValue);
    }

    //计算两个数字是否接近相等,阈值是dvalue
    public static bool IsApproximately(double a, double b, double dvalue)
    {
        double delta = a - b;
        return delta >= -dvalue && delta <= dvalue;
    }

你可能感兴趣的:(Unity3d技术)