def test_the_color_when_a_ray_misses__only_negative_intersection_t(): w = World() w.light = PointLight(Point(-10, 10, -10), Color(1, 1, 1)) w.objects = [Plane()] r = Ray(Point(0, 10, 0), Vector(0, 1, 1).normalize()) c = w.color_at(r) assert c == Color(0, 0, 0)
def test_a_point_light_has_a_position_and_intensity(): # Given intensity = Color(1, 1, 1) position = Point(0, 0, 0) # When light = PointLight(position, intensity) # Then assert light.position == position assert light.intensity == intensity
def test_shading_an_intersection_from_the_inside(): # Given w = default_world() w.light = PointLight(Point(0, 0.25, 0), Color(1, 1, 1)) r = Ray(Point(0, 0, 0), Vector(0, 0, 1)) shape = w.objects[1] i = Intersection(0.5, shape) # When comps = i.prepare_computations(r) c = w.shade_hit(comps) # Then assert c == Color(0.90498, 0.90498, 0.90498)
def test_lighting_with_the_light_behind_the_surface(): # Given m = Material() position = Point(0, 0, 0) eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, 10), Color(1, 1, 1)) object = Sphere() # When result = m.lighting(object, light, position, eyev, normalv) # Then assert result == Color(0.1, 0.1, 0.1)
def test_lighting_with_the_eye_in_the_path_of_the_reflection_vector(): # Given m = Material() position = Point(0, 0, 0) eyev = Vector(0, -sqrt(2) / 2, -sqrt(2) / 2) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 10, -10), Color(1, 1, 1)) object = Sphere() # When result = m.lighting(object, light, position, eyev, normalv) # Then assert result == Color(1.6364, 1.6364, 1.6364)
def test_lighting_with_the_eye_opposite_surface_light_offset_45degree(): # Given m = Material() position = Point(0, 0, 0) eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 10, -10), Color(1, 1, 1)) object = Sphere() # When result = m.lighting(object, light, position, eyev, normalv) # Then assert result == Color(0.7364, 0.7364, 0.7364)
def test_lighting_with_the_eye_between_light_and_surface_eye_offset_45degree(): # Given m = Material() position = Point(0, 0, 0) eyev = Vector(0, sqrt(2) / 2, sqrt(2) / 2) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, -10), Color(1, 1, 1)) object = Sphere() # When result = m.lighting(object, light, position, eyev, normalv) # Then assert result == Color(1.0, 1.0, 1.0)
def default_world(): light = PointLight(Point(-10, 10, -10), Color(1, 1, 1)) s1 = Sphere() s1.material.color = Color(0.8, 1.0, 0.6) s1.material.diffuse = 0.7 s1.material.specular = 0.2 s2 = Sphere() s2.transform = scaling(0.5, 0.5, 0.5) w = World() w.light = light w.objects = [s1, s2] return w
def test_default_world(): # Given light = PointLight(Point(-10, 10, -10), Color(1, 1, 1)) s1 = Sphere() s1.material.color = Color(0.8, 1.0, 0.6) s1.material.diffuse = 0.7 s1.material.specular = 0.2 s2 = Sphere() s2.transform = scaling(0.5, 0.5, 0.5) # When w = default_world() # Then assert w.light == light assert s1 in w.objects assert s2 in w.objects
def test__shade_hit__is_given_an_intersection_in_shadow(): # Given w = World() w.light = PointLight(Point(0, 0, -10), Color(1, 1, 1)) s1 = Sphere() w.objects.append(s1) s2 = Sphere() s2.transform = translation(0, 0, 10) w.objects.append(s2) r = Ray(Point(0, 0, 5), Vector(0, 0, 1)) i = Intersection(4, s2) # When comps = i.prepare_computations(r) c = w.shade_hit(comps) # Then assert c == Color(0.1, 0.1, 0.1)
def test_lighting_with_a_pattern_applied(): # Given m = Material() m.pattern = StripePattern(Color(1, 1, 1), Color(0, 0, 0)) m.ambient = 1 m.diffuse = 0 m.specular = 0 eyev = Vector(0, 0, -1) normalv = Vector(0, 0, -1) light = PointLight(Point(0, 0, -10), Color(1, 1, 1)) object = Sphere() # When c1 = m.lighting(object, light, Point(0.9, 0, 0), eyev, normalv) c2 = m.lighting(object, light, Point(1.1, 0, 0), eyev, normalv) # Then assert c1 == Color(1, 1, 1) assert c2 == Color(0, 0, 0)
def test__color_at__with_mutually_reflective_surfaces(): # Given w = World() w.light = PointLight(Point(0, 0, 0), Color(1, 1, 1)) lower = Plane() lower.material.reflective = 1 lower.transform = translation(0, -1, 0) w.objects.append(lower) upper = Plane() upper.material.reflective = 1 upper.transform = translation(0, 1, 0) w.objects.append(upper) r = Ray(Point(0, 0, 0), Vector(0, 1, 0)) # Then try: w.color_at(r) except RecursionError: pytest.fail("Unexpected RecursionError ...")
# right.material.pattern = pattern # right.material.diffuse = 0.7 # right.material.specular = 0.3 right.material.diffuse = 0 right.material.specular = 0 left = Sphere() left.transform = translation(-1.5, 0.33, -0.75) * scaling(0.33, 0.33, 0.33) left.material = Material() left.material.color = Color(1, 0.8, 0.1) # left.material.pattern = pattern left.material.diffuse = 0.7 left.material.specular = 0.3 cube = Cube() cube.transform = translation( 0, 0, 1) * rotation_y(pi / 4) * scaling(0.5, 0.5, 0.5) world = World() # world.objects = [floor, backdrop, backdrop2, middle, right, left] world.objects = [cube] world.light = PointLight(Point(-10, 10, -10), Color(1, 1, 1)) camera = Camera(100, 50, pi / 3) camera.transform = view_transform(Point(0, 1.5, -5), Point(0, 1, 0), Vector(0, 1, 0)) canvas = camera.render(world) print(canvas.to_ppm())
if __name__ == "__main__": ray_origin = Point(0, 0, -5) wall_z = 10 wall_size = 7.0 canvas_pixcels = 100 pixel_size = wall_size / canvas_pixcels half = wall_size / 2 canvas = Canvas(canvas_pixcels, canvas_pixcels) shape = Sphere() shape.material = Material() shape.material.color = Color(1, 0.2, 1) light_position = Point(-10, 10, -10) light_color = Color(1, 1, 1) light = PointLight(light_position, light_color) # for each row of pixels in the canvas for y in range(canvas_pixcels): # compute the world y coordinate (top = +half, bottom = -half) world_y = half - pixel_size * y for x in range(canvas_pixcels): # compute the world x coordinate (left = -half, right = half) world_x = -half + pixel_size * x # describe the point on the wall that the ray will target position = Point(world_x, world_y, wall_z) r = Ray(ray_origin, (position - ray_origin).normalize()) xs = shape.intersect(r)