def test_intersecting_a_translated_sphere_with_a_ray(): sphere = Sphere(transformation=transformations.translation(5, 0, 0)) ray = Ray(point(0, 0, -5), vector(0, 0, 1)) xs = sphere.intersect(ray) assert(len(xs) == 0)
def default_world(): light = PointLight(point(-10, 10, -10), white) m = Material(color=color(0.8, 1.0, 0.6), diffuse=0.7, specular=0.2) s1 = Sphere(material=m) s2 = Sphere(transformation=scaling(0.5, 0.5, 0.5)) return World(light, s1, s2)
def test_intersecting_a_scaled_sphere_with_a_ray(): sphere = Sphere(transformation=transformations.scaling(2, 2, 2)) ray = Ray(point(0, 0, -5), vector(0, 0, 1)) xs = sphere.intersect(ray) assert(xs[0].t == 3) assert(xs[1].t == 7)
def test_intersect_sets_the_object_on_the_intersection(): r = Ray(point(0, 0, -5), vector(0, 0, 1)) s = Sphere() xs = s.intersect(r) assert(len(xs) == 2) assert(xs[0].object is s) assert(xs[1].object is s)
def test_computing_the_normal_on_a_transformed_sphere(): s = transformations.scaling(1, 0.5, 1) r = transformations.rotation_z(math.pi/5) transform = transformations.concat(s, r) sphere = Sphere(transform) n = sphere.normal_at(point(0, math.sqrt(2)/2, -math.sqrt(2)/2)) assert(np.allclose(vector(0, 0.97014, -0.242535), n))
def test_shade_hit_is_given_an_intersection_in_shadow(): light = PointLight(point(0, 0, -10), color(1, 1, 1)) s1 = Sphere() s2 = Sphere(transformation=translation(0, 0, 10)) w = World(light, s1, s2) r = Ray(point(0, 0, 5), vector(0, 0, 1)) i = Intersection(4, s2) comps = i.prepare_computations(r) c = w.shade_hit(comps) assert(np.allclose(color(0.1, 0.1, 0.1), c))
def test_hit_should_offset_the_point(): r = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = Sphere(transformation=translation(0, 0, 1)) i = Intersection(5, shape) comps = i.prepare_computations(r) assert(comps.point[2] < -EPSILON/2)
def test_a_sphere_may_be_asigned_a_material(): m = Material(ambient=1) s = Sphere(material=m) actual_material = s.material assert(np.array_equal(m, actual_material))
def test_the_hit_when_an_intersection_occurs_on_the_outside(): r = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = Sphere() i = Intersection(4, shape) comps = i.prepare_computations(r) assert(comps.inside == False)
def test_aggregating_intersections(): s = Sphere() i1 = Intersection(1, s) i2 = Intersection(2, s) xs = Intersections(i1, i2) assert(xs[0].t == 1) assert(xs[1].t == 2)
def test_hit_when_all_intersections_have_positive_t(): s = Sphere() i1 = Intersection(1.0, s) i2 = Intersection(2.0, s) xs = Intersections(i2, i1) i = xs.hit() assert(i is i1)
def test_hit_when_some_intersections_have_negative_t(): s = Sphere() i1 = Intersection(-1, s) i2 = Intersection(1, s) xs = Intersections(i2, i1) i = xs.hit() assert(i is i2)
def test_hit_when_all_intersections_are_negative(): s = Sphere() i1 = Intersection(-2, s) i2 = Intersection(-1, s) xs = Intersections(i2, i1) i = xs.hit() assert(i is None)
def test_the_hit_when_an_intersection_occurs_on_the_inside(): r = Ray(point(0, 0, 0), vector(0, 0, 1)) shape = Sphere() i = Intersection(1, shape) comps = i.prepare_computations(r) assert(np.allclose(point(0, 0, 1), comps.point)) assert(np.allclose(vector(0, 0, -1), comps.eyev)) assert(comps.inside == True) assert(np.allclose(vector(0, 0, -1), comps.normalv))
def test_hit_is_always_the_lowest_non_negative_intersection(): s = Sphere() i1 = Intersection(5.0, s) i2 = Intersection(7.0, s) i3 = Intersection(-3, s) i4 = Intersection(2, s) xs = Intersections(i1, i2, i3, i4) i = xs.hit() assert(i is i4)
def test_precompute_the_state_of_an_intersection(): r = Ray(point(0, 0, -5), vector(0, 0, 1)) shape = Sphere() i = Intersection(4, shape) comps = i.prepare_computations(r) assert(comps.t == i.t) assert(comps.object is i.object) assert(np.allclose(point(0, 0, -1), comps.point)) assert(np.allclose(vector(0, 0, -1), comps.eyev)) assert(np.allclose(vector(0, 0, -1), comps.normalv))
def test_an_intersection_encapsulates_t_and_object(): s = Sphere() i = Intersection(3.5, s) assert(i.object is s) assert(i.t == 3.5)
from pytracer.spheres import Sphere from pytracer.transformations import scaling, rotation_y, rotation_x, translation, concat, view_transformation from pytracer.materials import Material from pytracer.colors import color from pytracer.camera import Camera from pytracer.tuples import point, vector from pytracer.lights import PointLight from pytracer.world import World import math floor_material = Material(color=color(1, 0.9, 0.9), specular=0) floor = Sphere(transformation=scaling(10, 0.01, 10), material=floor_material) left_wall_transformation = concat(translation(0, 0, 5), rotation_y(-math.pi / 4), rotation_x(math.pi / 2), scaling(10, 0.01, 10)) left_wall = Sphere(transformation=left_wall_transformation, material=floor_material) right_wall_transform = concat(translation(0, 0, 5), rotation_y(math.pi / 4), rotation_x(math.pi / 2), scaling(10, 0.01, 10)) right_wall = Sphere(transformation=right_wall_transform, material=floor_material) middle_transform = translation(-0.5, 1, 0.5) middle_material = Material(color=color(0.1, 1, 0.5), diffuse=0.7, specular=0.3) middle = Sphere(material=middle_material, transformation=middle_transform) right_transform = concat(translation(1.5, 0.5, -0.5), scaling(0.5, 0.5, 0.5)) right_material = Material(color=color(0.5, 1, 0.1), diffuse=0.7, specular=0.3)
def test_the_normal_is_a_normalized_vector(): p = math.sqrt(3)/3 n = Sphere().normal_at(point(p, p, p)) assert(np.allclose(tuples.normalize(n), n))
def test_identity_is_a_sphere_default_transformation(): sphere = Sphere() expected_transformation = transformations.identity_matrix actual_transformation = sphere.transformation assert(np.array_equal(expected_transformation(), actual_transformation()))
def test_a_sphere_has_a_material(): expected_material = Material() s = Sphere(material=expected_material) actual_material = s.material assert(expected_material is actual_material)
def test_computing_the_normal_on_a_translated_sphere(): sphere = Sphere(transformations.translation(0, 1, 0)) n = sphere.normal_at(point(0, 1.70711, -0.70711)) assert(np.allclose(vector(0, 0.70711, -0.70711), n))
def test_a_ray_intersects_a_sphere_at_a_tangent(): xs = Sphere().intersect(Ray(point(0, 1, -5), vector(0, 0, 1))) assert(len(xs) == 2) assert(xs[0].t == 5.0) assert(xs[1].t == 5.0)
def test_a_ray_intersects_a_sphere_at_two_points(): xs = Sphere().intersect(Ray(point(0, 0, -5), vector(0, 0, 1))) assert(len(xs) == 2) assert(xs[0].t == 4.0) assert(xs[1].t == 6.0)
def test_a_ray_misses_a_sphere(): xs = Sphere().intersect(Ray(point(0, 2, -5), vector(0, 0, 1))) assert(len(xs) == 0)
def test_a_ray_originates_inside_a_sphere(): xs = Sphere().intersect(Ray(point(0, 0, 0), vector(0, 0, 1))) assert(len(xs) == 2) assert(xs[0].t == -1.0) assert(xs[1].t == 1.0)
def test_a_sphere_behind_a_ary(): xs = Sphere().intersect(Ray(point(0, 0, 5), vector(0, 0, 1))) assert(len(xs) == 2) assert(xs[0].t == -6.0) assert(xs[1].t == -4.0)
def test_normal_on_a_sphere_at_a_non_axial_point(): p = math.sqrt(3)/3 n = Sphere().normal_at(point(p, p, p)) assert(np.allclose(vector(p, p, p), n))
def test_normal_on_a_sphere_at_a_point_on_the_z_axis(): n = Sphere().normal_at(point(0, 0, 1)) assert((vector(0, 0, 1) == n).all())