public static bool Cross(Sphere2D sphere, Sphere2D other, Vector2_ tp, ref Vector2_ hit)
    {
        if (sphere.Intersect(other))
        {
            return(true);
        }

        var o = other.center_;

        tp -= o;
        sphere.SetCenter(sphere.center_ - o);
        other.SetCenter(Vector2_.zero);

        other.radius += sphere.radius;

        var dir = tp - sphere.center_;
        var rr  = other.radius * other.radius * dir.sqrMagnitude;
        var t   = sphere.center_ + dir;
        var d   = sphere.x * t.y - t.x * sphere.y;
        var dd  = d * d;

        if (rr - dd > 0)
        {
            var proj = Vector2_.Project(-sphere.center_, dir.normalized);
            if (proj.magnitude <= dir.magnitude && Vector2_.Dot(proj, dir) > 0)
            {
                hit = proj + sphere.center_ + o;
                return(true);
            }
        }

        sphere.SetCenter(tp);

        if (sphere.Intersect(other))
        {
            hit = tp + o;
            return(true);
        }

        return(false);
    }
    public static bool Cross(Box2D box, Sphere2D other, Vector2_ tp, ref Vector2_ hit)
    {
        if (box.Intersect(other))
        {
            return(true);
        }

        var o = other.center_;

        tp -= o;
        box.SetCenter(box.center_ - o);
        other.SetCenter(Vector2_.zero);

        var dir = tp - box.center_;

        var rr = other.radius * other.radius * dir.sqrMagnitude;
        var t  = box.topLeft + dir;
        var d  = box.leftEdge * t.y - t.x * box.topEdge;
        var dd = d * d;

        if (rr - dd > 0)
        {
            var proj = Vector2_.Project(-box.topLeft, dir.normalized);
            if (proj.magnitude <= dir.magnitude && Vector2_.Dot(proj, dir) > 0)
            {
                hit = Vector2_.Project(-box.center_, dir.normalized) + box.center_ + o;
                return(true);
            }
        }

        t  = box.bottomRight + dir;
        d  = box.rightEdge * t.y - t.x * box.bottomEdge;
        dd = d * d;

        if (rr - dd > 0)
        {
            var proj = Vector2_.Project(-box.bottomRight, dir.normalized);
            if (proj.magnitude <= dir.magnitude && Vector2_.Dot(proj, dir) > 0)
            {
                hit = Vector2_.Project(-box.center_, dir.normalized) + box.center_ + o;
                return(true);
            }
        }

        t  = box.topRight + dir;
        d  = box.rightEdge * t.y - t.x * box.topEdge;
        dd = d * d;

        if (rr - dd > 0)
        {
            var proj = Vector2_.Project(-box.topRight, dir.normalized);
            if (proj.magnitude <= dir.magnitude && Vector2_.Dot(proj, dir) > 0)
            {
                hit = Vector2_.Project(-box.center_, dir.normalized) + box.center_ + o;
                return(true);
            }
        }

        t  = box.bottomLeft + dir;
        d  = box.leftEdge * t.y - t.x * box.bottomEdge;
        dd = d * d;

        if (rr - dd > 0)
        {
            var proj = Vector2_.Project(-box.bottomLeft, dir.normalized);
            if (proj.magnitude <= dir.magnitude && Vector2_.Dot(proj, dir) > 0)
            {
                hit = Vector2_.Project(-box.center_, dir.normalized) + box.center_ + o;
                return(true);
            }
        }

        box.SetCenter(tp);

        if (box.Intersect(other))
        {
            hit = tp + o;
            return(true);
        }

        return(false);
    }