def test_the_color_when_ray_misses(self): world = default_world() ray = Ray(point(0, 0, -5), vector(0, 1, 0)) c = color_at(world, ray) self.assertEqual(color(0, 0, 0), c)
def test_the_color_when_ray_hits(self): world = default_world() ray = Ray(point(0, 0, -5), vector(0, 0, 1)) c = color_at(world, ray) self.assert_tuple_equals(color(0.38066, 0.47583, 0.2855), c, 0.001)
def test_intersecting_translated_sphere_with_ray(self): r = Ray(point(0, 0, -5), vector(0, 0, 1)) s = Sphere() s.set_transform(translation(5, 0, 0)) xs = s.intersect(r) self.assertEqual(0, len(xs))
def test_sphere_behind_ray(self): r = Ray(point(0, 0, 5), vector(0, 0, 1)) s = Sphere() xs = s.intersect(r) self.assertEqual(2, len(xs)) self.assertEqual(-6, xs[0].t) self.assertEqual(-4, xs[1].t)
def test_ray_originates_inside_sphere(self): r = Ray(point(0, 0, 0), vector(0, 0, 1)) s = Sphere() xs = s.intersect(r) self.assertEqual(2, len(xs)) self.assertEqual(-1, xs[0].t) self.assertEqual(1, xs[1].t)
def test_ray_intersects_sphere_at_tangent(self): r = Ray(point(0, 1, -5), vector(0, 0, 1)) s = Sphere() xs = s.intersect(r) self.assertEqual(2, len(xs)) self.assertEqual(5, xs[0].t) self.assertEqual(5, xs[1].t)
def test_intersection_occurs_on_the_outside(self): ray = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = Sphere() xs = Intersection(4, shape) xs.prepare_hit(ray) self.assertEqual(False, xs.inside)
def test_intersect_sets_object_on_intersection(self): r = Ray(point(0, 0, -5), vector(0, 0, 1)) s = sphere.Sphere() xs = s.intersect(r) self.assertEqual(2, len(xs)) self.assertEqual(s, xs[0].shape) self.assertEqual(s, xs[1].shape)
def test_precomputing_state_of_intersection(self): ray = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = Sphere() xs = Intersection(4, shape) xs.prepare_hit(ray) self.assertEqual(point(0, 0, -1), xs.point) self.assertEqual(vector(0, 0, -1), xs.eyev) self.assertEqual(vector(0, 0, -1), xs.normalv)
def test_shading_and_intersection(self): world = default_world() ray = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = world.objects[0] xs = Intersection(4, shape) xs.prepare_hit(ray) c = shade_hit(world, xs) self.assert_tuple_equals(color(0.38066, 0.47583, 0.2855), c, 0.001)
def test_intersecting_scaled_sphere_with_ray(self): r = Ray(point(0, 0, -5), vector(0, 0, 1)) s = Sphere() s.set_transform(scaling(2, 2, 2)) xs = s.intersect(r) self.assertEqual(2, len(xs)) self.assertEqual(3, xs[0].t) self.assertEqual(7, xs[1].t)
def test_shading_an_intersection_form_the_inside(self): world = default_world() world.light = PointLight(point(0, 0.25, 0), color(1, 1, 1)) ray = Ray(point(0, 0, 0), vector(0, 0, 1)) shape = world.objects[1] xs = Intersection(0.5, shape) xs.prepare_hit(ray) c = shade_hit(world, xs) self.assert_tuple_equals(color(0.90498, 0.90498, 0.90498), c, 0.001)
def test_the_color_with_an_intersection_behind_the_ray(self): world = default_world() outer = world.objects[0] outer.material.ambient = 1 inner = world.objects[1] inner.material.ambient = 1 ray = Ray(point(0, 0, 0.75), vector(0, 0, -1)) c = color_at(world, ray) self.assertEqual(inner.material.color, c)
def test_intersection_occurs_on_the_inside(self): ray = Ray(point(0, 0, 0), vector(0, 0, 1)) shape = Sphere() xs = Intersection(1, shape) xs.prepare_hit(ray) self.assertEqual(point(0, 0, 1), xs.point) self.assertEqual(vector(0, 0, -1), xs.eyev) self.assertEqual(True, xs.inside) self.assertEqual(vector(0, 0, -1), xs.normalv)
def test_intersect_world_with_ray(self): world = default_world() ray = Ray(point(0, 0, -5), vector(0, 0, 1)) xs = intersect_world(world, ray) self.assertEqual(4, len(xs)) self.assertEqual(4, xs[0].t) self.assertEqual(4.5, xs[1].t) self.assertEqual(5.5, xs[2].t) self.assertEqual(6, xs[3].t)
def ray_for_pixel(camera, px, py): x_offset = (px + 0.5) * camera.pixel_size y_offset = (py + 0.5) * camera.pixel_size world_x = camera.half_width - x_offset world_y = camera.half_height - y_offset pixel = camera.transform.inverse() * point(world_x, world_y, -1) origin = camera.transform.inverse() * point(0, 0, 0) direction = (pixel - origin).normalize() return Ray(origin, direction)
def intersect(self, r: Ray): ray2 = r.transform(self.transform.inverse()) sphere_to_ray = ray2.origin - point(0, 0, 0) a = ray2.direction.dot(ray2.direction) b = 2 * ray2.direction.dot(sphere_to_ray) c = sphere_to_ray.dot(sphere_to_ray) - 1 delta = b * b - 4 * a * c if delta < 0: return [] t1 = (-b - sqrt(delta)) / (2 * a) t2 = (-b + sqrt(delta)) / (2 * a) i1 = intersections.Intersection(t1, self) i2 = intersections.Intersection(t2, self) return [i1, i2]
def test_computing_point_from_distance(self): r = Ray(point(2, 3, 4), vector(1, 0, 0)) self.assertEqual(point(2, 3, 4), r.position(0)) self.assertEqual(point(3, 3, 4), r.position(1)) self.assertEqual(point(1, 3, 4), r.position(-1)) self.assertEqual(point(4.5, 3, 4), r.position(2.5))
from renderer.rays import Ray from renderer.sphere import Sphere from renderer.tuples import point, color s = Sphere() ray_origin = point(0, 0, -5) wall_z = 10 wall_size = 7.0 canvas_pixels = 1000 pixel_size = wall_size / canvas_pixels half = wall_size / 2 c = Canvas(canvas_pixels, canvas_pixels) col = color(1, 1, 0) start_time = time.time() for y in range(canvas_pixels): elapsed_time = time.time() - start_time if elapsed_time > 0 and y > 0: print("time_to_finish: " + str(1.0 * (canvas_pixels - y) / (1.0 * y / elapsed_time))) world_y = half - pixel_size * y for x in range(canvas_pixels): world_x = -half + pixel_size * x position = point(world_x, world_y, wall_z) ray = Ray(ray_origin, (position - ray_origin)) xs = s.intersect(ray) if hit(xs): c.write_pixel(x, y, col) c.save_to_file('shadow_on_the_wall.ppm')
def test_ray_misses_sphere(self): r = Ray(point(0, 2, -5), vector(0, 0, 1)) s = Sphere() xs = s.intersect(r) self.assertEqual(0, len(xs))
def test_scaling_ray(self): r = Ray(point(1, 2, 3), vector(0, 1, 0)) m = scaling(2, 3, 4) r2 = r.transform(m) self.assertEqual(point(2, 6, 12), r2.origin) self.assertEqual(vector(0, 3, 0), r2.direction)
def test_creating_ray(self): p = point(1, 2, 3) v = vector(4, 5, 6) r = Ray(p, v) self.assertEqual(p, r.origin) self.assertEqual(v, r.direction)
wall_size = 7.0 canvas_pixels = 1000 pixel_size = wall_size / canvas_pixels half = wall_size / 2 c = Canvas(canvas_pixels, canvas_pixels) col = color(1, 0, 0) start_time = time.time() for y in range(canvas_pixels): elapsed_time = time.time() - start_time if elapsed_time > 0 and y > 0: print("time_to_finish: " + str(1.0 * (canvas_pixels - y) / (1.0 * y / elapsed_time))) world_y = half - pixel_size * y for x in range(canvas_pixels): world_x = -half + pixel_size * x position = point(world_x, world_y, wall_z) ray = Ray(ray_origin, (position - ray_origin).normalize()) xs = s.intersect(ray) if hit(xs): hit_point = ray.position(hit(xs).t) norma_at_hit_point = s.normal_at(hit_point) eye = -ray.direction color = s.material.lighting(light, hit_point, eye, norma_at_hit_point) c.write_pixel(x, y, color) c.save_to_file('sphere6.ppm')
def test_translating_ray(self): r = Ray(point(1, 2, 3), vector(0, 1, 0)) m = translation(3, 4, 5) r2 = r.transform(m) self.assertEqual(point(4, 6, 8), r2.origin) self.assertEqual(vector(0, 1, 0), r2.direction)