import torch


def triple_points_along_normals(x, n, eps, homogeneous=False):
    """
    Convert a point cloud equipped with normals into a point cloud with points pertubed along those normals.
    Each point X with normal N, in the input gets converted to 3 points:
        (X, X+eps*N, X-eps*N) which have occupancy values (0, eps, -eps)
    :param x: The input points of shape [N, 3]
    :param n: The input normals of shape [N, 3]
    :param eps: The amount to perturb points about each normal
    :param homogeneous: If true, return the points in homogeneous coordinates
    :return: A pair, (X, O) consisting of the new point cloud X and point occupancies O
    """
    x_in = x - n * eps
    x_out = x + n * eps

    x_triples = torch.cat([x, x_in, x_out], dim=0)
    occ_triples = torch.cat([torch.zeros(x.shape[0]),
                             -torch.ones(x.shape[0]),
                             torch.ones(x.shape[0])]).to(x) * eps
    if homogeneous:
        x_triples = torch.cat([x_triples, torch.ones(x_triples.shape[0], 1, dtype=x_triples.dtype)], dim=-1)

    return x_triples, occ_triples