C# 分离轴定理问题

C# 分离轴定理问题,c#,xna,2d,game-physics,C#,Xna,2d,Game Physics,我目前正在尝试为轴对齐和定向的边界框添加重叠测试仪,但解决方案似乎只有在OBB的角度介于-10和+10之间时才能准确工作。当角度接近+90度时,碰撞区域似乎首先移动到OBB的右半部分,然后变得不存在。在90到270之间,我无法得到一个重叠,当它达到360度时,该区域再次准确地注册 对这个问题有任何了解都会很好。我用正X表示0度,逆时针递增 干杯 编辑:做了更多的研究,意识到将一个向量投影到另一个向量需要的不仅仅是点积。任何人都可以给我一个正确的版本的检查轴方法下面相当漂亮,请:) 编辑2:实际上

我目前正在尝试为轴对齐和定向的边界框添加重叠测试仪,但解决方案似乎只有在OBB的角度介于-10和+10之间时才能准确工作。当角度接近+90度时,碰撞区域似乎首先移动到OBB的右半部分,然后变得不存在。在90到270之间,我无法得到一个重叠,当它达到360度时,该区域再次准确地注册

对这个问题有任何了解都会很好。我用正X表示0度,逆时针递增

干杯

编辑:做了更多的研究,意识到将一个向量投影到另一个向量需要的不仅仅是点积。任何人都可以给我一个正确的版本的检查轴方法下面相当漂亮,请:)

编辑2:实际上,我认为应该是点积,因为投影到的向量是单位长度

public static bool overlapAABB_OBB(AABB a, OBB o)
    {
        float rads = MathHelper.ToRadians(-o.angle);
        T = Vector2.Subtract(o.position, a.position);
        Ax.X = 1;
        Ax.Y = 0;
        Ay.X = 0;
        Ay.Y = 1;
        Ox.X = (float)Math.Cos(rads);
        Ox.Y = (float)Math.Sin(rads);
        Oy.X = -Ox.Y;
        Oy.Y = Ox.X;
        if (checkAX(a, o) &&
           checkAY(a, o) &&
           checkOX(a, o) &&
           checkOY(a, o))
            return true;
        else
            return false;
    }

    private static bool checkAX(AABB a, OBB o)
    {
        float TAx = Vector2.Dot(T, Ax);
        float WoOxAx = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax);
        float HoOyAx = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax);
        if (TAx > a.halfWidth + WoOxAx + HoOyAx)
            return false;
        else
            return true;
    }

    private static bool checkAY(AABB a, OBB o)
    {
        float TAy = Vector2.Dot(T, Ay);
        float WoOxAy = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ay);
        float HoOyAy = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ay);
        if (TAy > a.halfHeight + WoOxAy + HoOyAy)
            return false;
        else
            return true;
    }

    private static bool checkOX(AABB a, OBB o)
    {
        float TOx = Vector2.Dot(T, Ox);
        float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox);
        float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox);
        if (TOx > o.halfHeight + WaAxOx + HaAyOx)
            return false;
        else
            return true;
    }

    private static bool checkOY(AABB a, OBB o)
    {
        float TOy = Vector2.Dot(T, Oy);
        float WaAxOy = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Oy);
        float HaAyOy = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Oy);
        if (TOy > o.halfHeight + WaAxOy + HaAyOy)
            return false;
        else
            return true;
    }

我在GameDev.stackexchange上发布了这个问题,并从修复了这个问题的rraallvv那里收到了这个答案

当两个矢量之间的角度大于90º时,点积为负,为使代码正常工作,需要取点积的绝对值

//...
private static bool checkAX(AABB a, OBB o)
{
    float TAx    = Math.Abs( Vector2.Dot(T, Ax) );
    float WoOxAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax) );
    float HoOyAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax) );
    if (TAx > a.halfWidth + WoOxAx + HoOyAx)
        return false;
    else
        return true;
}
//...

这也适用于
checkAY
checkOX
checkOY
我在GameDev.stackexchange上发布了这个问题,并从修复了这个问题的rraallvv那里收到了这个答案

当两个矢量之间的角度大于90º时,点积为负,为使代码正常工作,需要取点积的绝对值

//...
private static bool checkAX(AABB a, OBB o)
{
    float TAx    = Math.Abs( Vector2.Dot(T, Ax) );
    float WoOxAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax) );
    float HoOyAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax) );
    if (TAx > a.halfWidth + WoOxAx + HoOyAx)
        return false;
    else
        return true;
}
//...

这也适用于
checkAY
checkOX
checkOY
除了Mazk1985提供的修复外,checkOX()函数中还存在打字错误。o、 半高应为o.halfWidth,如下所示:

private static bool checkOX(AABB a, OBB o)
{
    float TOx = Vector2.Dot(T, Ox);
    float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox);
    float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox);
    if (TOx > o.halfWidth + WaAxOx + HaAyOx)
        return false;
    else
        return true;
}

除了Mazk1985提供的修复外,checkOX()函数中还有一个输入错误。o、 半高应为o.halfWidth,如下所示:

private static bool checkOX(AABB a, OBB o)
{
    float TOx = Vector2.Dot(T, Ox);
    float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox);
    float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox);
    if (TOx > o.halfWidth + WaAxOx + HaAyOx)
        return false;
    else
        return true;
}