'Get the 4x4 Perspective Transfromation matrix used for PTN.'

def get_transform_matrix(self, view_out):

    num_views = self._params.num_views
    focal_length = self._params.focal_length
    focal_range = self._params.focal_range
    phi = 30
    theta_interval = (360.0 / num_views)
    theta = (theta_interval * view_out)
    camera_matrix = np.zeros((4, 4), dtype=np.float32)
    intrinsic_matrix = np.eye(4, dtype=np.float32)
    extrinsic_matrix = np.eye(4, dtype=np.float32)
    sin_phi = np.sin(((float(phi) / 180.0) * np.pi))
    cos_phi = np.cos(((float(phi) / 180.0) * np.pi))
    sin_theta = np.sin(((float((- theta)) / 180.0) * np.pi))
    cos_theta = np.cos(((float((- theta)) / 180.0) * np.pi))
    rotation_azimuth = np.zeros((3, 3), dtype=np.float32)
    rotation_azimuth[(0, 0)] = cos_theta
    rotation_azimuth[(2, 2)] = cos_theta
    rotation_azimuth[(0, 2)] = (- sin_theta)
    rotation_azimuth[(2, 0)] = sin_theta
    rotation_azimuth[(1, 1)] = 1.0
    rotation_elevation = np.zeros((3, 3), dtype=np.float32)
    rotation_elevation[(0, 0)] = cos_phi
    rotation_elevation[(0, 1)] = sin_phi
    rotation_elevation[(1, 0)] = (- sin_phi)
    rotation_elevation[(1, 1)] = cos_phi
    rotation_elevation[(2, 2)] = 1.0
    rotation_matrix = np.matmul(rotation_azimuth, rotation_elevation)
    displacement = np.zeros((3, 1), dtype=np.float32)
    displacement[(0, 0)] = (float(focal_length) + (float(focal_range) / 2.0))
    displacement = np.matmul(rotation_matrix, displacement)
    extrinsic_matrix[0:3, 0:3] = rotation_matrix
    extrinsic_matrix[0:3, 3:4] = (- displacement)
    intrinsic_matrix[(2, 2)] = (1.0 / float(focal_length))
    intrinsic_matrix[(1, 1)] = (1.0 / float(focal_length))
    camera_matrix = np.matmul(extrinsic_matrix, intrinsic_matrix)
    return camera_matrix
