import torch


def box_center_to_corners(b):
    """
    Converts a set of oriented bounding boxes from
    centered representation (x_c, y_c, w, h, theta) to corner representation (x0, y0, ..., x3, y3).
    Arguments:
        b (Tensor[N, 6]): boxes to be converted. They are
            expected to be in (x_c, y_c, w, h, c, s) format.
            * c, s: unnormalized cos, sin
    Returns:
        c (Tensor[N, 8]): converted boxes in (x0, y0, ..., x3, y3) format, where
            the corners are sorted counterclockwise.
    """
    # print(b.shape)
    x_c, y_c, w, h, c, s = b.unbind(-1)  # [N,]
    # print(x_c.shape)
    s = 2 * s - 1
    # center = torch.stack([x_c, y_c], dim=-1).repeat(1, 4)  # [N, 8]
    center = torch.stack([x_c, y_c, x_c, y_c, x_c, y_c, x_c, y_c], dim=-1)

    dx = 0.5 * w
    dy = 0.5 * h
    c = c + 1e-5
    s = s + 1e-5
    cos = c / ((c ** 2 + s ** 2).sqrt() + 1e-10)
    sin = s / ((c ** 2 + s ** 2).sqrt() + 1e-10)

    dxcos = dx * cos
    dxsin = dx * sin
    dycos = dy * cos
    dysin = dy * sin

    dxy = [
        -dxcos + dysin,
        -dxsin - dycos,
        dxcos + dysin,
        dxsin - dycos,
        dxcos - dysin,
        dxsin + dycos,
        -dxcos - dysin,
        -dxsin + dycos,
    ]

    return center + torch.stack(dxy, dim=-1)