def test_the_normal_is_a_normalized_vector():
    # Given
    s = Sphere()
    # When
    n = s.normal_at(Point(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3))
    # Then
    assert n == n.normalize()
def test_the_normal_on_a_sphere_at_a_point_at_a_nonaxial_axis():
    # Given
    s = Sphere()
    # When
    n = s.normal_at(Point(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3))
    # Then
    assert n == Vector(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3)
def test_the_normal_on_a_sphere_at_a_point_on_the_z_axis():
    # Given
    s = Sphere()
    # When
    n = s.normal_at(Point(0, 0, 1))
    # Then
    assert n == Vector(0, 0, 1)
def test_computing_the_normal_on_a_translated_sphere():
    # Given
    s = Sphere()
    s.transform = translation(0, 1, 0)
    # When
    n = s.normal_at(Point(0, 1.70711, -0.70711))
    # Then
    assert n == Vector(0, 0.70711, -0.70711)
def test_a_ray_misses_s_sphere():
    # Given
    r = Ray(Point(0, 2, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    assert len(xs) == 0
def test_commputing_the_normal_on_a_transformed_sphere():
    # Given
    s = Sphere()
    m = scaling(1, 0.5, 1) * rotation_z(pi / 5)
    s.transform = m
    # When
    n = s.normal_at(Point(0, sqrt(2) / 2, -sqrt(2) / 2))
    # Then
    assert n == Vector(0, 0.97014, -0.24254)
def test_intersecting_a_translated_sphere_with_a_ray():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    s.transform = translation(5, 0, 0)
    xs = s.intersect(r)
    # Then
    assert len(xs) == 0
def test_a_pattern_with_an_object_transformation():
    # Given
    shape = Sphere()
    shape.transform = scaling(2, 2, 2)
    pattern = MockPattern()
    # When
    c = pattern.pattern_at_shape(shape, Point(2, 3, 4))
    # Then
    assert c == Color(1, 1.5, 2)
def test_a_pattern_with_both_an_object_and_a_pattern_transformation():
    # Given
    shape = Sphere()
    shape.transform = scaling(2, 2, 2)
    pattern = MockPattern()
    pattern.transform = translation(0.5, 1, 1.5)
    # When
    c = pattern.pattern_at_shape(shape, Point(2.5, 3, 3.5))
    # Then
    assert c == Color(0.75, 0.5, 0.25)
def test_a_ray_originates_inside_a_sphere():
    # Given
    r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    assert len(xs) == 2
    assert xs[0].t == -1.0
    assert xs[1].t == 1.0
def test_a_sphere_is_behind_a_ray():
    # Given
    r = Ray(Point(0, 0, 5), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    assert len(xs) == 2
    assert xs[0].t == -6.0
    assert xs[1].t == -4.0
def test_a_ray_intersects_a_sphere_at_a_tangent():
    # Then
    r = Ray(Point(0, 1, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    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():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    assert len(xs) == 2
    assert xs[0].t == 4.0
    assert xs[1].t == 6.0
def test_intersect_sets_the_object_on_the_intersection():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    xs = s.intersect(r)
    # Then
    assert len(xs) == 2
    assert xs[0].object == s
    assert xs[1].object == s
def test_intersecting_a_scaled_sphere_with_a_ray():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = Sphere()
    # When
    s.transform = scaling(2, 2, 2)
    xs = s.intersect(r)
    # Then
    assert len(xs) == 2
    assert xs[0].t == 3
    assert xs[1].t == 7
示例#16
0
def test_the_hit_should_offset_the_point():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    shape = Sphere()
    shape.transform = translation(0, 0, 1)
    i = Intersection(5, shape)
    # When
    comps = i.prepare_computations(r)
    # Then
    assert comps.over_point.z < -EPSILON / 2
    assert comps.point.z > comps.over_point.z
def test_intersecting_a_transformed_group():
    # Given
    g = Group()
    g.transform = scaling(2, 2, 2)
    s = Sphere()
    s.transform = translation(5, 0, 0)
    g.add_child(s)
    # When
    r = Ray(Point(10, 0, -10), Vector(0, 0, 1))
    xs = g.intersect(r)
    # Then
    assert len(xs) == 2
示例#18
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
示例#19
0
def test_converting_a_normal_from_object_to_world_space():
    # Given
    g1 = Group()
    g1.transform = rotation_y(pi / 2)
    g2 = Group()
    g2.transform = scaling(1, 2, 3)
    g1.add_child(g2)
    s = Sphere()
    s.transform = translation(5, 0, 0)
    g2.add_child(s)
    # When
    n = s.normal_to_world(Vector(sqrt(3) / 3, sqrt(3) / 3, sqrt(3) / 3))
    # Then
    assert n == Vector(0.28571, 0.42857, -0.85714)
示例#20
0
def test_finding_the_normal_on_a_child_object():
    # Given
    g1 = Group()
    g1.transform = rotation_y(pi / 2)
    g2 = Group()
    g2.transform = scaling(1, 2, 3)
    g1.add_child(g2)
    s = Sphere()
    s.transform = translation(5, 0, 0)
    g2.add_child(s)
    # When
    n = s.normal_at(Point(1.7321, 1.1547, -5.5774))
    # Then
    assert n == Vector(0.2857, 0.42854, -0.85716)
示例#21
0
def test_converting_a_point_from_world_to_object_space():
    # Given
    g1 = Group()
    g1.transform = rotation_y(pi / 2)
    g2 = Group()
    g2.transform = scaling(2, 2, 2)
    g1.add_child(g2)
    s = Sphere()
    s.transform = translation(5, 0, 0)
    g2.add_child(s)
    # When
    p = s.world_to_object(Point(-2, 0, -10))
    # Then
    assert p == Point(0, 0, -1)
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)
示例#24
0
def test_an_intersection_encapsulates_t_and_object():
    # Given
    s = Sphere()
    # When
    i = Intersection(3.5, s)
    # Then
    assert i.t == 3.5
    assert i.object == s
示例#25
0
def test_the_hit__when_an_intersection_occurs_on_the_outside():
    # Given
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    shape = Sphere()
    i = Intersection(4, shape)
    # When
    comps = i.prepare_computations(r)
    # Then
    assert comps.inside is False
示例#26
0
def test_the_hit__when_all_intersections_have_positive_t():
    # Given
    s = Sphere()
    i1 = Intersection(1, s)
    i2 = Intersection(2, s)
    xs = Intersections(i2, i1)
    # When
    i = xs.hit()
    # Then
    assert i == i1
示例#27
0
def test_the_hit__when_all_intersections_have_netative_t():
    # Given
    s = Sphere()
    i1 = Intersection(-2, s)
    i2 = Intersection(-1, s)
    xs = Intersections(i2, i1)
    # When
    i = xs.hit()
    # Then
    assert i is None
示例#28
0
def test_the_hit__when_some_intersections_have_negative_t():
    # Given
    s = Sphere()
    i1 = Intersection(-1, s)
    i2 = Intersection(1, s)
    xs = Intersections(i2, i1)
    # When
    i = xs.hit()
    # Then
    assert i == i2
示例#29
0
def test_aggregating_intersections():
    # Given
    s = Sphere()
    i1 = Intersection(1, s)
    i2 = Intersection(2, s)
    # When
    xs = Intersections(i1, i2)
    # Then
    assert len(xs) == 2
    assert xs[0].t == 1
    assert xs[1].t == 2
示例#30
0
def test_the_hit_is_always_the_lowest_nonnegative_intersection():
    # Given
    s = Sphere()
    i1 = Intersection(5, s)
    i2 = Intersection(7, s)
    i3 = Intersection(-3, s)
    i4 = Intersection(2, s)
    xs = Intersections(i1, i2, i3, i4)
    # When
    i = xs.hit()
    # Then
    assert i == i4