【Unity】回転する矩形と円形の接触判定

はじめに

以前矩形と円形の接触判定を行う処理の記事を書きましたが,
今回は矩形が回転した場合にも対応します.
yshinya09.hatenablog.com

完成形

以下のように回転する矩形と円形の接触判定をとります.

実装

図形の定義

円形と矩形のクラスをそれぞれ以下のように定義しました。
矩形は Unity の Rect クラスだと回転を持てない為, 定義しなおしました。

// 円形.
record Circle2d(Vector2 Center, float Radius);
// 矩形.
record Rect2d(Vector2 Center, float width, float height, float rotation);

接触判定

private static bool Overlap(Circle2d circle, Rect2d rect2d)
{
    var rect = new Rect(rect2d.Center.x - rect2d.Width / 2.0f, rect2d.Center.y - rect2d.Height / 2.0f, rect2d.Width, rect2d.Height);;

    var cos = Mathf.Cos(rect2d.Rotation * Mathf.Deg2Rad);
    var sin = Mathf.Sin(rect2d.Rotation * Mathf.Deg2Rad);
    var diff = circle.Center - rect.center;
    var pos = rect.center + new Vector2(diff.x * cos + diff.y * -sin, diff.x * sin + diff.y * cos);

    // Rect 上で最も Circle の Center に近い点を求める.
    var x = Mathf.Max(rect.xMin, Mathf.Min(pos.x, rect.xMax));
    var y = Mathf.Max(rect.yMin, Mathf.Min(pos.y, rect.yMax));
    var nearestPoint = new Vector2(x, y);

    // Rect 上で最も Circle の Center に近い点が, Circle の半径より近いをチェック.
    return (nearestPoint - pos).sqrMagnitude <= circle.Radius * circle.Radius;
}