示例#1
0
    def test_reflective_transparent_material(self):
        """Test shade_hit with a reflective, transparent material"""

        world = copy.deepcopy(self.default_scene)

        floor = shapes.Plane(material=materials.Material(
            reflective=0.5, transparency=0.5, refractive_index=1.5))
        floor.set_transform(transforms.Translate(0, -1, 0))

        ball = shapes.Sphere(material=materials.Material(
            color=colors.Color(1, 0, 0), ambient=0.5))
        ball.set_transform(transforms.Translate(0, -3.5, -0.5))

        r = rays.Ray(points.Point(0, 0, -3),
                     vectors.Vector(0, -math.sqrt(2) / 2,
                                    math.sqrt(2) / 2))
        xs = intersections.Intersections(
            intersections.Intersection(floor, math.sqrt(2)))

        world.add_object(floor)
        world.add_object(ball)

        comps = xs.intersections[0].precompute(r, all_intersections=xs)

        color, _ = world.shade_hit(comps, remaining=5)

        self.assertEqual(color, colors.Color(0.93391, 0.69643, 0.69243))
    def test_refractive_index_intersections(self):
        """Test we can calculate the refractive indices between intersections"""

        # Set up a scene with three glass spheres.  One at the origin with size
        # 2 then inside of that 2 that are offset along z by different amounts
        A = shapes.Sphere(material=materials.Material(refractive_index=1.5,
                                                      transparency=1.0))
        B = shapes.Sphere(material=materials.Material(refractive_index=2.0,
                                                      transparency=1.0))
        C = shapes.Sphere(material=materials.Material(refractive_index=2.5,
                                                      transparency=1.0))

        A.set_transform(transforms.Scale(2, 2, 2))
        B.set_transform(transforms.Translate(0, 0, -0.25))
        C.set_transform(transforms.Translate(0, 0, 0.25))

        r = rays.Ray(points.Point(0, 0, -4), vectors.Vector(0, 0, 1))

        xs = intersections.Intersections(intersections.Intersection(A, 2),
                                         intersections.Intersection(B, 2.75),
                                         intersections.Intersection(C, 3.25),
                                         intersections.Intersection(B, 4.75),
                                         intersections.Intersection(C, 5.25),
                                         intersections.Intersection(A, 6))

        expected_results = [
            {
                "n1": 1.0,
                "n2": 1.5
            },
            {
                "n1": 1.5,
                "n2": 2.0
            },
            {
                "n1": 2.0,
                "n2": 2.5
            },
            {
                "n1": 2.5,
                "n2": 2.5
            },
            {
                "n1": 2.5,
                "n2": 1.5
            },
            {
                "n1": 1.5,
                "n2": 1.0
            },
        ]

        for index, expected in enumerate(expected_results):

            comps = xs.intersections[index].precompute(r, all_intersections=xs)
            self.assertDictEqual(expected, {"n1": comps.n1, "n2": comps.n2})
示例#3
0
    def test_reflection__reflective(self):
        """Test the reflection color of a reflective material is not black"""

        p = shapes.Plane(material=materials.Material(reflective=0.5))
        p.set_transform(transforms.Translate(0, -1, 0))

        world = copy.deepcopy(self.default_scene)

        world.objects.append(p)

        r = rays.Ray(points.Point(0, 0, -3),
                     vectors.Vector(0, -math.sqrt(2) / 2,
                                    math.sqrt(2) / 2))

        i = intersections.Intersection(p, math.sqrt(2))

        comps = i.precompute(r)

        # Test reflected color alone
        result, _ = world.reflected_color(comps)
        self.assertEqual(result, colors.Color(0.19032, 0.2379, 0.14274))

        # Now test the reflected color is added to the surface color
        result, _ = world.shade_hit(comps)
        self.assertEqual(result, colors.Color(0.87677, 0.92436, 0.82918))
示例#4
0
    def test_shadows__full_scene(self):
        """Test that we identify a shadow in a full scene"""

        # First sphere is at z=10
        s1 = shapes.Sphere()
        s1.set_transform(transforms.Translate(0, 0, 10))

        # Second sphere is at the origin
        s2 = shapes.Sphere()
        s2.material = materials.Material()

        # Light is at z=-10
        l1 = lights.Light(position=points.Point(0, 0, -10),
                          intensity=colors.Color(1, 1, 1))

        scene = scenes.Scene(objects=[s1, s2], lights=[l1])

        # The ray is at z=5 (i.e. between the spheres), pointing at the further
        # out sphere
        ray = rays.Ray(points.Point(0, 0, 5), vectors.Vector(0, 0, 1))

        isection = intersections.Intersection(s2, 4)
        comps = isection.precompute(ray)

        result, _ = scene.shade_hit(comps)

        self.assertEqual(result, colors.Color(0.1, 0.1, 0.1))
示例#5
0
    def test_translate_vector_is_noop(self):
        """Verify that translating a vector has no effect"""

        v = vectors.Vector(1, 2, 3)
        T = transforms.Translate(5, -3, 2)

        v2 = T * v
        self.assertEqual(v, v2)
示例#6
0
    def test_move_camera(self):
        """Test we can move the camera (well... move the world)"""
        from_point = points.Point(0, 0, 9)
        to_point = points.Point(0, 0, 0)
        up = vectors.Vector(0, 1, 0)

        result = transforms.ViewTransform(from_point, to_point, up)

        self.assertEqual(result, transforms.Translate(0, 0, -9))
示例#7
0
    def test_chained_transforms(self):
        """Test we can chain together transforms with the apply function"""
        point = points.Point(1, 0, 1)

        p2 = point.apply(transforms.RotateX(math.pi/2)) \
                  .apply(transforms.Scale(5, 5, 5)) \
                  .apply(transforms.Translate(10, 5, 7))

        self.assertEqual(p2, points.Point(15, 0, 7))
示例#8
0
    def test_pattern_object_transformation(self):
        """Test that pattern is affected by pattern and object transforms"""

        shape = shapes.Sphere()
        shape.set_transform(transforms.Scale(2, 2, 2))

        p = patterns.StripePattern(WHITE, BLACK)
        p.set_transform(transforms.Translate(0.5, 0, 0))

        self.assertEqual(p.pattern_at_shape(shape, points.Point(2.5, 0, 0)),
                         WHITE)
示例#9
0
    def test_reflection__infinite_recursion(self):
        """Test that we don't break if there is infinite recursion"""

        # Two parallel planes
        s1 = shapes.Plane(material=materials.Material(reflective=1))
        s1.set_transform(transforms.Translate(0, -1, 0))

        # Second sphere is at the origin
        s2 = shapes.Plane(material=materials.Material(reflective=1))
        s2.set_transform(transforms.Translate(0, 1, 0))

        # Light is at z=-10
        l1 = lights.Light(position=points.Point(0, 0, 0),
                          intensity=colors.Color(1, 1, 1))

        scene = scenes.Scene(objects=[s1, s2], lights=[l1])

        r = rays.Ray(points.Point(0, 0, 0), vectors.Vector(0, 1, 0))

        # If this is working the following will NOT cause a stack trace
        scene.color_at(r)
示例#10
0
    def test_intersections_with_transformed_ray__translation(self):
        """Test we get the correct intersections after adding a translation
        to a shape
        """

        s = shapes.Sphere()
        s.set_transform(transforms.Translate(5, 0, 0))

        r = rays.Ray(points.Point(0, 0, -5), vectors.Vector(0, 0, 1))

        result = s.intersect(r)
        self.assertTrue(len(result.intersections) == 0)
示例#11
0
    def test_translate_point(self):
        """Test that if we multiply a translate matrix by a point it moves it"""

        p = points.Point(-3, 4, 5)
        T = transforms.Translate(5, -3, 2)

        p2 = T * p
        self.assertEqual(p2, points.Point(2, 1, 7))

        # Translating by the inverse of the translate matrix moves the
        # opposite direction

        p3 = T.inverse() * p
        self.assertEqual(p3, points.Point(-8, 7, 3))
示例#12
0
    def test_ray_transforms(self):
        """Test that we can transform a ray"""

        origin = points.Point(1, 2, 3)
        direction = vectors.Vector(0, 1, 0)
        r = rays.Ray(origin, direction)

        r2 = r.transform(transforms.Translate(3, 4, 5))
        self.assertEqual(r2.origin, points.Point(4, 6, 8))
        self.assertEqual(r2.direction, vectors.Vector(0, 1, 0))

        r3 = r.transform(transforms.Scale(2, 3, 4))
        self.assertEqual(r3.origin, points.Point(2, 6, 12))
        self.assertEqual(r3.direction, vectors.Vector(0, 3, 0))
示例#13
0
    def test_normal_at__transformed(self):
        """Test we can calculate normal vectors on a transformed sphere"""

        s = shapes.Sphere()
        s.set_transform(transforms.Translate(0, 1, 0))
        n = s.normal_at(points.Point(0, 1.70711, -0.70711))

        self.assertEqual(n, vectors.Vector(0, 0.70711, -0.70711))

        s.set_transform(
            transforms.Scale(1, 0.5, 1) * transforms.RotateZ(math.pi / 5))

        n = s.normal_at(points.Point(0, math.sqrt(2) / 2, -math.sqrt(2) / 2))
        self.assertEqual(n, vectors.Vector(0, 0.97014, -0.24254))
示例#14
0
    def test_precompute__over_vector(self):
        """Test that we calculate a vector just inside of the surface of a
        shape
        """

        r = rays.Ray(points.Point(0, 0, -5), vectors.Vector(0, 0, 1))

        s = shapes.Sphere()
        s.set_transform(transforms.Translate(0, 0, 1))

        i = intersections.Intersection(s, 5)

        computations = i.precompute(r)
        self.assertTrue(computations.under_point.z > computations.point.z)
        self.assertTrue(computations.under_point.z > intersections.EPSILON / 2)
示例#15
0
    def test_changed_transform(self):
        """Test that we can change the transform on a shape"""

        s = shapes.Sphere()
        s.set_transform(transforms.Translate(6, 7, 8))
        self.assertEqual(s.transform, transforms.Translate(6, 7, 8))