def _cast_ray(self, point): """ Casts a ray from pixel at point coordinates and returns its color. :param point: tuple with x, y coordinates of the pixel :param P_inv: inverted camera projection matrix :return: point color of the nearest wall """ ray_direction_cam_frame = self.K_inv @ np.hstack( [point[0], point[1], 1]) point_on_image_plane_world_frame = self.C2W @ np.hstack( [ray_direction_cam_frame, 1]) point_on_image_plane_world_frame = point_on_image_plane_world_frame / point_on_image_plane_world_frame[ 3] # p1 - point in camera center, p2 - point on image plane p1 = self.position p2 = point_on_image_plane_world_frame[:2] color = (0, 0, 0) for wall in self.environment.map.walls: # q1, q2 - wall vertices q1 = wall.vertex1 q2 = wall.vertex2 t = intersect_ray_segment(p1, p2, q1, q2) if t is not None: # Check that point is in front of the camera intersection_point = q1 + t * (q2 - q1) direction = np.dot(p2 - p1, intersection_point - p2) if direction > 0: color = wall.get_color_at(t) return color
def test_intersect_ray_segment_collinear(self): """ Test for intersect_ray_segment() function when a ray and a line are collinear. :return: """ p1 = np.array([0, 0]) p2 = np.array([4, 0]) q1 = np.array([5, 0]) q2 = np.array([7, 0]) u = intersect_ray_segment(p1, p2, q1, q2) self.assertIsNone(u)
def test_intersect_ray_segment_intersect(self): """ Test for intersect_ray_segment() function when there is an intersection. :return: """ p1 = np.array([0, 0]) p2 = np.array([4, 0]) q1 = np.array([5, -1]) q2 = np.array([5, 3]) u = intersect_ray_segment(p1, p2, q1, q2) self.assertEqual(u, 0.25)
def test_intersect_ray_segment_not_intersect(self): """ Test for intersect_ray_segment() function when there is no intersection. :return: """ p1 = np.array([0, 0]) p2 = np.array([4, 0]) q1 = np.array([5, 1]) q2 = np.array([5, 3]) u = intersect_ray_segment(p1, p2, q1, q2) self.assertIsNone(u)