import torch


def points_in_box(corners, points):
    """
    Checks whether points are inside the box.

    Picks one corner as reference (p1) and computes the vector to a target point (v).
    Then for each of the 3 axes, project v onto the axis and compare the length.
    Inspired by: https://math.stackexchange.com/a/1552579
    :param corners: (3, 8).
    :param points: <torch.float: 3, n>.
    :return: <torch.bool: n, >.
    """

    p1 = corners[:, 0]
    p_x = corners[:, 3]
    p_y = corners[:, 4]
    p_z = corners[:, 1]
    # p_x = corners[:, 4]
    # p_y = corners[:, 1]
    # p_z = corners[:, 3]

    i = p_x - p1
    j = p_y - p1
    k = p_z - p1

    v = points - p1.reshape((-1, 1))

    iv = torch.matmul(i, v)
    jv = torch.matmul(j, v)
    kv = torch.matmul(k, v)

    mask_x = torch.logical_and(0 <= iv, iv <= torch.matmul(i, i))
    mask_y = torch.logical_and(0 <= jv, jv <= torch.matmul(j, j))
    mask_z = torch.logical_and(0 <= kv, kv <= torch.matmul(k, k))
    mask = torch.logical_and(torch.logical_and(mask_x, mask_y), mask_z)

    return mask