圆与OBB矩形是否相交

发布时间 2023-11-06 23:30:53作者: yanghui01

1) 以矩形的中心作为原点,建立坐标系。

2) 算出矩形的旋转角度,然后将矩形和圆都旋转回去。

3) 就可以按照普通的圆与矩形是否相交来判断了。 

 

关于圆心旋转后的坐标计算

先求出oc与x轴的夹角,然后根据旋转角度就可计算出c'的坐标

c'.x = r * cos(θ+θ2), c'.y = r * sin(θ+θ2)

会用到的三角函数公式:

sin(θ+θ2)=sin(θ)*cos(θ2)+cos(θ)*sin(θ2)

cos(θ+θ2)=cos(θ)*cos(θ2)-sin(θ)*sin(θ2)

且已知:

c.x = r * cos(θ), c.y = r * sin(θ)

所以:

c'.x = r * cos(θ+θ2) = r*cos(θ)*cos(θ2) - r*sin(θ)*sin(θ2) = c.x*cos(θ2) - c.y*sin(θ2)

c'.y = r * sin(θ+θ2) = r*sin(θ)*cos(θ2) + r*cos(θ)*sin(θ2) = c.y*cos(θ2) + c.x*sin(θ2)

 

//圆与OBB矩形是否相交
public static bool IsCircleOBBIntersect(Vector2 a, Vector2 b, Vector2 d, Vector2 e, Vector2 c, float r)
{
    var o = (d - a) * 2; //矩形中心点
    //将矩形中心点作为原点建立坐标系
    a -= o;
    b -= o;
    c -= o;

    var right = Vector2.right;

    var abNM = (b - a).normalized;
    var dot = Vector2.Dot(abNM, right); //cos(θ2)
    var cross = V2Cross(ref abNM, ref right); //sin(θ2)

    c = new Vector2(c.x * dot - c.y * cross, c.y * dot + c.x * cross); //不带旋转的圆心坐标

    //不带旋转的矩形对角坐标
    var halfSize = (d - a) * 0.5f;
    a = -halfSize;
    d = halfSize;

    //将圆转换到第一象限
    c.x = Mathf.Abs(c.x);
    c.y = Mathf.Abs(c.y);

    //圆心到矩形的最短距离
    var dc = c - d;
    dc.x = Mathf.Max(dc.x, 0);
    dc.y = Mathf.Max(dc.y, 0);

    //最短距离<=r, 则和矩形相交
    return dc.sqrMagnitude <= r * r;
}

 

参考

简易碰撞检测原理--图形相交测试_相交检测算法-CSDN博客