def test_intersect_single_sphere(): surface = Surface(color=RED) s = Sphere(position=(10, 0, 0), radius=5, surface=surface) scene = Scene(objects=[s], background=BLACK) ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, 0, 0)) obtained = scene.find_intersect(ray) assert obtained == (5, s)
def test_cast_on_single_sphere(): surface = Surface(color=RED) s = Sphere(position=(10, 0, 0), radius=5, surface=surface) scene = Scene(objects=[s], background=BLACK) ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, 0, 0)) obtained = scene.cast_ray(ray) assert obtained.x != 0 assert obtained.y == 0 assert obtained.z == 0
def test_cast_miss_single_sphere(): surface = Surface(color=RED) s = Sphere(position=(10, 0, 0), radius=5, surface=surface) scene = Scene(objects=[s], background=BLACK) # Ray is above the sphere and should miss it ray = Ray(origin=Vector3(0, 6, 0), direction=Vector3(1, 0, 0)) obtained = scene.cast_ray(ray) assert obtained.x == 0 assert obtained.y == 0 assert obtained.z == 0
def parse_scene(scene_str) -> Tuple[Scene, Camera]: parsed = yaml.load(scene_str) surfaces, objects, lights = {}, {}, {} for surface in parsed["surfaces"]: surfaces[surface] = Surface(**parsed["surfaces"][surface]) for obj in parsed["objects"]: props = parsed["objects"][obj] obj_type = props.pop("type") props["surface"] = surfaces[props["surface"]] if obj_type == "sphere": objects[obj] = Sphere(**props) elif obj_type == "plane": objects[obj] = Plane(**props) for light in parsed["lights"]: props = parsed["lights"][light] lights[light] = LightSource(**props) scene_args = parsed["scene"] if "scene" in parsed else {} scene = Scene(objects=list(objects.values()), light_sources=list(lights.values()), **scene_args) camera = Camera(**parsed["camera"]) return scene, camera
def test_4_spheres(): surface = Surface(color=RED) s1 = Sphere(position=(10, -4, -4), radius=5, surface=surface) s2 = Sphere(position=(10, -4, 4), radius=5, surface=surface) s3 = Sphere(position=(10, 4, -4), radius=5, surface=surface) s4 = Sphere(position=(10, 4, 4), radius=5, surface=surface) scene = Scene(objects=[s1, s2, s3, s4], background=BLACK) # Center ray, miss all spheres ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, 0, 0)) d, obtained = scene.find_intersect(ray) assert obtained is None ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, 0.2, 0.2)) d, intersected = scene.find_intersect(ray) assert intersected == s4 assert d == approx(6.967, rel=1e-3) ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, -0.2, 0.2)) d, intersected = scene.find_intersect(ray) assert intersected == s2 assert d == approx(6.967, rel=1e-3) ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, -0.2, -0.2)) d, intersected = scene.find_intersect(ray) assert intersected == s1 assert d == approx(6.967, rel=1e-3) ray = Ray(origin=Vector3(0, 0, 0), direction=Vector3(1, 0.2, -0.2)) d, intersected = scene.find_intersect(ray) assert intersected == s3 assert d == approx(6.967, rel=1e-3)
def test_two_spheres(): scene = Scene() light2 = LightSource(Vector3(0, -20, -10)) surface = Surface(color=Vector3(100, 0, 0)) sphere1 = Sphere(Vector3(40, 4, 0), 3, surface) sphere2 = Sphere(Vector3(30, -4, 0), 3, surface) scene.objects.append(sphere1) scene.objects.append(sphere2) scene.light_sources.append(light2) camera = Camera(Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(1, 1, 0)) screen = PngScreen("test_two_spheres.png", 400, 400) camera.set_screen(screen) camera.ray_for_pixel(50, 50) camera.take_picture(scene)
def test_sphere_position(): scene = Scene() light2 = LightSource(Vector3(0, -20, -20)) surface = Surface(color=Vector3(100, 0, 0)) sphere1 = Sphere(Vector3(25, -3, -5), 3, surface) scene.objects.append(sphere1) scene.light_sources.append(light2) camera = Camera(Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(1, 1, 0), screen_distance=10) screen = PngScreen("test_sphere_position.png", 600, 400) camera.set_screen(screen) camera.ray_for_pixel(50, 50) camera.take_picture(scene)