def test_a_gradient_linearly_interpolates_between_colors():
    # Given
    pattern = GradientPattern(WHITE, BLACK)
    # Then
    assert pattern.pattern_at(Point(0.25, 0, 0)) == Color(0.75, 0.75, 0.75)
    assert pattern.pattern_at(Point(0.5, 0, 0)) == Color(0.5, 0.5, 0.5)
    assert pattern.pattern_at(Point(0.75, 0, 0)) == Color(0.25, 0.25, 0.25)
def test_creating_a_canvas():
    # Given
    c = Canvas(10, 20)
    # Then
    assert c.width == 10
    assert c.height == 20

    for h in range(20):
        for w in range(10):
            assert c.pixels[h][w] == Color(0, 0, 0)

    b = Color(0, 0, 0)
    assert c.pixels == \
        [
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
            [b, b, b, b, b, b, b, b, b, b],
        ]
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 color_at(self, ray, remaining=4):
        xs = self.intersect_world(ray)
        if not xs:
            return Color(0, 0, 0)

        hit = xs.hit()
        if not hit:
            return Color(0, 0, 0)

        comps = hit.prepare_computations(ray, xs)
        return self.shade_hit(comps, remaining)
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)
示例#6
0
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)
示例#7
0
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)
示例#8
0
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)
示例#9
0
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)
示例#10
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
示例#12
0
    def reflected_color(self, comps, remaining=4):
        if comps.object.material.reflective == 0 or remaining <= 0:
            return Color(0, 0, 0)
        reflect_ray = Ray(comps.over_point, comps.reflectv)
        color = self.color_at(reflect_ray, remaining - 1)

        return color * comps.object.material.reflective
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)
示例#14
0
    def lighting(self, object, light, point, eyev, normalv, in_shadow=False):
        if self.pattern:
            color = self.pattern.pattern_at_shape(object, point)
        else:
            color = self.color

        effective_color = color * light.intensity
        ambient = effective_color * self.ambient
        if in_shadow:
            return ambient

        lightv = (light.position - point).normalize()
        light_dot_normal = lightv.dot(normalv)

        black = Color(0, 0, 0)
        if light_dot_normal < 0:
            diffuse = black
            specular = black
        else:
            diffuse = effective_color * self.diffuse * light_dot_normal

            reflectv = (-lightv).reflect(normalv)
            reflect_dot_eye = reflectv.dot(eyev)
            if reflect_dot_eye <= 0:
                specular = black
            else:
                factor = pow(reflect_dot_eye, self.shininess)
                specular = light.intensity * self.specular * factor

        return ambient + diffuse + specular
def test_colors_are_red_green_blue_tuples():
    # Given
    c = Color(-0.5, 0.4, 1.7)
    # Then
    assert c.red == -0.5
    assert c.green == 0.4
    assert c.blue == 1.7
def test_constructing_the_ppm_pixel_data():
    # Given
    c = Canvas(5, 3)
    c1 = Color(1.5, 0, 0)
    c2 = Color(0, 0.5, 0)
    c3 = Color(-0.5, 0, 1)
    # When
    c.write_pixel(0, 0, c1)
    c.write_pixel(2, 1, c2)
    c.write_pixel(4, 2, c3)
    ppm = c.to_ppm()
    # Then
    assert ppm.split("\n")[3:6] == \
        ["255 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
         "0 0 0 0 0 0 0 128 0 0 0 0 0 0 0",
         "0 0 0 0 0 0 0 0 0 0 0 0 0 0 255"]
def test_the_color_when_a_ray_hits():
    # Given
    w = default_world()
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    # When
    c = w.color_at(r)
    # Then
    assert c == Color(0.38066, 0.47583, 0.2855)
def test_the_color_when_a_ray_misses():
    # Given
    w = default_world()
    r = Ray(Point(0, 0, -5), Vector(0, 1, 0))
    # When
    c = w.color_at(r)
    # Then
    assert c == Color(0, 0, 0)
示例#19
0
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_a_pattern_with_a_pattern_transformation():
    # Given
    shape = Sphere()
    pattern = MockPattern()
    pattern.transform = scaling(2, 2, 2)
    # When
    c = pattern.pattern_at_shape(shape, Point(2, 3, 4))
    # Then
    assert c == Color(1, 1.5, 2)
示例#21
0
    def refracted_color(self, comps, remaining):
        if remaining == 0 or comps.object.material.transparency == 0:
            return Color(0, 0, 0)

        n_ratio = comps.n1 / comps.n2
        cos_i = comps.eyev.dot(comps.normalv)
        sin2_t = n_ratio**2 * (1 - cos_i**2)
        if sin2_t > 1:
            return Color(0, 0, 0)

        cos_t = sqrt(1.0 - sin2_t)
        direction = comps.normalv * \
            (n_ratio * cos_i - cos_t) - comps.eyev * n_ratio

        refracted_ray = Ray(comps.under_point, direction)
        color = self.color_at(refracted_ray, remaining - 1)

        return color * comps.object.material.transparency
示例#22
0
def test_the_default_material():
    # Given
    m = Material()
    # Then
    assert m.color == Color(1, 1, 1)
    assert m.ambient == 0.1
    assert m.diffuse == 0.9
    assert m.specular == 0.9
    assert m.shininess == 200.0
示例#23
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_writing_pixels_to_a_canvas():
    # Given
    c = Canvas(10, 20)
    red = Color(1, 0, 0)
    # When
    c.write_pixel(2, 3, red)
    # Then
    assert c.pixel_at(2, 3) == red
    assert c.pixels[3][2] == red
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)
示例#26
0
 def __init__(self):
     self.color = Color(1, 1, 1)
     self.ambient = 0.1
     self.diffuse = 0.9
     self.specular = 0.9
     self.shininess = 200.0
     self.pattern = None
     self.reflective = 0.0
     self.transparency = 0.0
     self.refractive_index = 1.0
def test_the_refracted_color_with_an_opaque_surface():
    # Given
    w = default_world()
    shape = w.objects[0]
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    xs = Intersections(Intersection(4, shape), Intersection(6, shape))
    # When
    comps = xs[0].prepare_computations(r, xs)
    c = w.refracted_color(comps, 5)
    # Then
    assert c == Color(0, 0, 0)
def test_shading_an_intersection():
    # Given
    w = default_world()
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    shape = w.objects[0]
    i = Intersection(4, shape)
    # When
    comps = i.prepare_computations(r)
    c = w.shade_hit(comps)
    # Then
    assert c == Color(0.38066, 0.47583, 0.2855)
def test_the_reflected_color_for_a_nonreflective_material():
    # Given
    w = default_world()
    r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
    shape = Sphere()
    shape.material.ambient = 1
    i = Intersection(1, shape)
    # When
    comps = i.prepare_computations(r)
    color = w.reflected_color(comps)
    # Then
    assert color == Color(0, 0, 0)  # black
def test_rendering_a_world_with_a_camera():
    # Given
    w = default_world()
    c = Camera(11, 11, pi / 2)
    f = Point(0, 0, -5)
    to = Point(0, 0, 0)
    up = Vector(0, 1, 0)
    c.transform = view_transform(f, to, up)
    # When
    image = c.render(w)
    # Then
    assert image.pixel_at(5, 5) == Color(0.38066, 0.47583, 0.2855)