Exemple #1
0
 def test_findinf_n1_n2_at_various_intersections(self):
     a = GlassSphere()
     a.transform = Transformations.scaling(2, 2, 2)
     a.material.refractive_index = 1.5
     b = GlassSphere()
     b.transform = Transformations.translation(0, 0, -0.25)
     b.material.refractive_index = 2.0
     c = GlassSphere()
     c.transform = Transformations.translation(0, 0, 0.25)
     c.material.refractive_index = 2.5
     r = Ray(Point(0, 0, -4), Vector(0, 0, 1))
     xs = Intersection.intersections(Intersection(2, a), Intersection(2.75, b), Intersection(3.25, c), Intersection(4.75, b), Intersection(5.25, c), Intersection(6, a))
     RefractiveIndices = namedtuple("RefractiveIndices", ["n1", "n2"])
     refractive_indices_list = [
         RefractiveIndices(1.0, 1.5),
         RefractiveIndices(1.5, 2.0),
         RefractiveIndices(2.0, 2.5),
         RefractiveIndices(2.5, 2.5),
         RefractiveIndices(2.5, 1.5),
         RefractiveIndices(1.5, 1.0)
     ]
     for index, refractive_index in enumerate(refractive_indices_list):
         comps = Computations.prepare_computations(xs[index], r, xs)
         print(comps.n1)
         print(comps.n2)
         self.assertEqual(comps.n1, refractive_index.n1)
         self.assertEqual(comps.n2, refractive_index.n2)
Exemple #2
0
 def test_subdivide_csg_subdivide_children(self):
     s1 = Sphere()
     s1.transform = Transformations.translation(-1.5, 0, 0)
     s2 = Sphere()
     s2.transform = Transformations.translation(1.5, 0, 0)
     left = Group()
     left.add_child(s1)
     left.add_child(s2)
     s3 = Sphere()
     s3.transform = Transformations.translation(0, 0, -1.5)
     s4 = Sphere()
     s4.transform = Transformations.translation(0, 0, 1.5)
     right = Group()
     right.add_child(s3)
     right.add_child(s4)
     shape = CSG("difference", left, right)
     shape.divide(1)
     self.assertIsInstance(left.members[0], Group)
     self.assertEqual(left.members[0].members, [s1])
     self.assertIsInstance(left.members[1], Group)
     self.assertEqual(left.members[1].members, [s2])
     self.assertIsInstance(right.members[0], Group)
     self.assertEqual(right.members[0].members, [s3])
     self.assertIsInstance(right.members[1], Group)
     self.assertEqual(right.members[1].members, [s4])
Exemple #3
0
 def test_color_at_with_mutually_reflective_surfaces(self):
     w = World()
     w.light = PointLight(Point(0, 0, 0), Color(1, 1, 1))
     lower = Plane()
     lower.material.reflective = 1
     lower.transform = Transformations.translation(0, -1, 0)
     w.objects.append(lower)
     upper = Plane()
     upper.material.reflective = 1
     upper.transform = Transformations.translation(0, 1, 0)
     w.objects.append(upper)
     r = Ray(Point(0, 0, 0), Vector(0, 1, 0))
     self.assertIsNotNone(World.color_at(w, r))
Exemple #4
0
 def test_partitioning_group_children(self):
     s1 = Sphere()
     s1.transform = Transformations.translation(-2, 0, 0)
     s2 = Sphere()
     s2.transform = Transformations.translation(2, 0, 0)
     s3 = Sphere()
     g = Group()
     g.add_child(s1)
     g.add_child(s2)
     g.add_child(s3)
     (left, right) = g.partition_children()
     self.assertEqual(g.members, [s3])
     self.assertEqual(left, [s1])
     self.assertEqual(right, [s2])
Exemple #5
0
 def test_group_bounding_box_contains_children(self):
     s = Sphere()
     s.transform = Transformations.translation(2, 5, -3).dot(
         Transformations.scaling(2, 2, 2))
     c = Cylinder()
     c.minimum = -2
     c.maximum = 2
     c.transform = Transformations.translation(-4, -1, 4).dot(
         Transformations.scaling(0.5, 1, 0.5))
     shape = Group()
     shape.add_child(s)
     shape.add_child(c)
     box = shape.bounds_of()
     self.assertEqual(box.min, Point(-4.5, -3, -5))
     self.assertEqual(box.max, Point(4, 7, 4.5))
Exemple #6
0
 def test_pattern_object_and_pattern_transformation(self):
     shape = Sphere()
     shape.transform = Transformations.scaling(2, 2, 2)
     pattern = Pattern.test_pattern()
     pattern.transform = Transformations.translation(0.5, 1, 1.5)
     c = pattern.pattern_at_shape(shape, Point(2.5, 3, 3.5))
     self.assertEqual(c, Color(0.75, 0.5, 0.25))
Exemple #7
0
 def test_chained_transformations(self):
     p = Point(1, 0, 1)
     a = Transformations.rotation_x(math.pi / 2)
     b = Transformations.scaling(5, 5, 5)
     c = Transformations.translation(10, 5, 7)
     t = c.dot(b.dot(a))
     self.assertEqual(Matrix.multiply_tuple(t, p), Point(15, 0, 7))
 def test_intersect_translated_shape_with_ray(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     s = Shape.test_shape()
     s.transform = Transformations.translation(5, 0, 0)
     xs = s.intersect(r)
     self.assertEqual(s.saved_ray.origin, Point(-5, 0, -5))
     self.assertEqual(s.saved_ray.direction, Vector(0, 0, 1))
Exemple #9
0
 def test_transformation_move_world(self):
     from_point = Point(0, 0, 8)
     to = Point(0, 0, 0)
     up = Vector(0, 1, 0)
     t = World.view_transform(from_point, to, up)
     self.assertTrue(
         np.array_equal(t, Transformations.translation(0, 0, -8)))
Exemple #10
0
 def test_hit_offset_point(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     shape = Sphere()
     shape.transform = Transformations.translation(0, 0, 1)
     i = Intersection(5, shape)
     comps = Computations.prepare_computations(i, r)
     self.assertLess(comps.over_point.z, -Constants.epsilon / 2)
     self.assertGreater(comps.point.z, comps.over_point.z)
Exemple #11
0
 def test_csg_bounding_box(self):
     left = Sphere()
     right = Sphere()
     right.transform = Transformations.translation(2, 3, 4)
     shape = CSG("difference", left, right)
     box = shape.bounds_of()
     self.assertEqual(box.min, Point(-1, -1, -1))
     self.assertEqual(box.max, Point(3, 4, 5))
Exemple #12
0
 def test_intersecting_ray_with_nonempty_group(self):
     g = Group()
     s1 = Sphere()
     s2 = Sphere()
     s2.transform = Transformations.translation(0, 0, -3)
     s3 = Sphere()
     s3.transform = Transformations.translation(5, 0, 0)
     g.add_child(s1)
     g.add_child(s2)
     g.add_child(s3)
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     xs = g.local_intersect(r)
     self.assertEqual(len(xs), 4)
     self.assertEqual(xs[0].object, s2)
     self.assertEqual(xs[1].object, s2)
     self.assertEqual(xs[2].object, s1)
     self.assertEqual(xs[3].object, s1)
 def test_ray_camera_transformed(self):
     c = Camera(201, 101, math.pi / 2)
     c.transform = Transformations.rotation_y(math.pi / 4).dot(
         Transformations.translation(0, -2, 5))
     r = Camera.ray_for_pixel(c, 100, 50)
     self.assertEqual(r.origin, Point(0, 2, -5))
     self.assertEqual(r.direction,
                      Vector(math.sqrt(2) / 2, 0, -math.sqrt(2) / 2))
Exemple #14
0
 def test_group_partitions_children(self):
     s1 = Sphere()
     s1.transform = Transformations.translation(-2, -2, 0)
     s2 = Sphere()
     s2.transform = Transformations.translation(-2, 2, 0)
     s3 = Sphere()
     s3.transform = Transformations.scaling(4, 4, 4)
     g = Group()
     g.add_child(s1)
     g.add_child(s2)
     g.add_child(s3)
     g.divide(1)
     self.assertEqual(g.members[0], s3)
     subgroup = g.members[1]
     self.assertIsInstance(subgroup, Group)
     self.assertEqual(len(subgroup.members), 2)
     self.assertEqual(subgroup.members[0].members, [s1])
     self.assertEqual(subgroup.members[1].members, [s2])
Exemple #15
0
 def test_intersecting_transformed_group(self):
     g = Group()
     g.transform = Transformations.scaling(2, 2, 2)
     s = Sphere()
     s.transform = Transformations.translation(5, 0, 0)
     g.add_child(s)
     r = Ray(Point(10, 0, -10), Vector(0, 0, 1))
     xs = g.intersect(r)
     self.assertEqual(len(xs), 2)
Exemple #16
0
 def test_under_point_offset_below_surface(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     shape = GlassSphere()
     shape.transform = Transformations.translation(0, 0, 1)
     i = Intersection(5, shape)
     xs = Intersection.intersections(i)
     comps = Computations.prepare_computations(i, r, xs)
     self.assertGreater(comps.under_point.z, Constants.epsilon / 2)
     self.assertLess(comps.point.z, comps.under_point.z)
Exemple #17
0
 def test_shade_hit_with_transparent_material(self):
     w = World.default_world()
     floor = Plane()
     floor.transform = Transformations.translation(0, -1, 0)
     floor.material.transparency = 0.5
     floor.material.refractive_index = 1.5
     w.objects.append(floor)
     ball = Sphere()
     ball.material.color = Color(1, 0, 0)
     ball.material.ambient = 0.5
     ball.transform = Transformations.translation(0, -3.5, -0.5)
     w.objects.append(ball)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     xs = Intersection.intersections(Intersection(math.sqrt(2), floor))
     comps = Computations.prepare_computations(xs[0], r, xs)
     color = World.shade_hit(w, comps, 5)
     self.assertEqual(color, Color(0.93642, 0.68642, 0.68642))
 def test_converting_normal_from_object_to_world_space(self):
     g1 = Group()
     g1.transform = Transformations.rotation_y(math.pi / 2)
     g2 = Group()
     g2.transform = Transformations.scaling(1, 2, 3)
     g1.add_child(g2)
     s = Sphere()
     s.transform = Transformations.translation(5, 0, 0)
     g2.add_child(s)
     n = s.normal_to_world(Vector(math.sqrt(3) /3, math.sqrt(3) / 3, math.sqrt(3) / 3))
     self.assertEqual(n, Vector(0.2857, 0.4286, -0.8571))
 def test_converting_point_from_world_to_object_space(self):
     g1 = Group()
     g1.transform = Transformations.rotation_y(math.pi / 2)
     g2 = Group()
     g2.transform = Transformations.scaling(2, 2, 2)
     g1.add_child(g2)
     s = Sphere()
     s.transform = Transformations.translation(5, 0, 0)
     g2.add_child(s)
     p = s.world_to_object(Point(-2, 0, -10))
     self.assertEqual(p, Point(0, 0, -1))
 def test_finding_normal_on_child_object(self):
     g1 = Group()
     g1.transform = Transformations.rotation_y(math.pi / 2)
     g2 = Group()
     g2.transform = Transformations.scaling(1, 2, 3)
     g1.add_child(g2)
     s = Sphere()
     s.transform = Transformations.translation(5, 0, 0)
     g2.add_child(s)
     n = s.normal_at(Point(1.7321, 1.1547, -5.5774))
     self.assertEqual(n, Vector(0.2857, 0.4286, -0.8571))
Exemple #21
0
 def test_ray_hits_csg_object(self):
     s1 = Sphere()
     s2 = Sphere()
     s2.transform = Transformations.translation(0, 0, 0.5)
     c = CSG("union", s1, s2)
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     xs = c.local_intersect(r)
     self.assertEqual(len(xs), 2)
     self.assertEqual(xs[0].t, 4)
     self.assertEqual(xs[0].object, s1)
     self.assertEqual(xs[1].t, 6.5)
     self.assertEqual(xs[1].object, s2)
Exemple #22
0
 def test_reflected_color_at_maximum_recursive_depth(self):
     w = World.default_world()
     shape = Plane()
     shape.material.reflective = 0.5
     shape.transform = Transformations.translation(0, -1, 0)
     w.objects.append(shape)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     i = Intersection(math.sqrt(2), shape)
     comps = Computations.prepare_computations(i, r)
     color = World.reflected_color(w, comps, 0)
     self.assertEqual(color, Color(0, 0, 0))
Exemple #23
0
 def test_subdividing_group_too_few_children(self):
     s1 = Sphere()
     s1.transform = Transformations.translation(-2, 0, 0)
     s2 = Sphere()
     s2.transform = Transformations.translation(2, 1, 0)
     s3 = Sphere()
     s3.transform = Transformations.translation(2, -1, 0)
     subgroup = Group()
     subgroup.add_child(s1)
     subgroup.add_child(s2)
     subgroup.add_child(s3)
     s4 = Sphere()
     g = Group()
     g.add_child(subgroup)
     g.add_child(s4)
     g.divide(3)
     self.assertEqual(g.members[0], subgroup)
     self.assertEqual(g.members[1], s4)
     self.assertEqual(len(subgroup.members), 2)
     self.assertEqual(subgroup.members[0].members, [s1])
     self.assertEqual(subgroup.members[1].members, [s2, s3])
Exemple #24
0
 def test_shade_hit_reflective_material(self):
     w = World.default_world()
     shape = Plane()
     shape.material.reflective = 0.5
     shape.transform = Transformations.translation(0, -1, 0)
     w.objects.append(shape)
     r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2,
                                     math.sqrt(2) / 2))
     i = Intersection(math.sqrt(2), shape)
     comps = Computations.prepare_computations(i, r)
     color = World.shade_hit(w, comps)
     self.assertEqual(color, Color(0.87677, 0.92436, 0.82918))
Exemple #25
0
 def test_shade_hit_intersection_in_shadow(self):
     w = World()
     w.light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
     s1 = Sphere()
     w.objects.append(s1)
     s2 = Sphere()
     s2.transform = Transformations.translation(0, 0, 10)
     w.objects.append(s2)
     r = Ray(Point(0, 0, 5), Vector(0, 0, 1))
     i = Intersection(4, s2)
     comps = Computations.prepare_computations(i, r)
     c = World.shade_hit(w, comps)
     self.assertEqual(c, Color(0.1, 0.1, 0.1))
Exemple #26
0
 def test_individual_transformations(self):
     p = Point(1, 0, 1)
     a = Transformations.rotation_x(math.pi / 2)
     b = Transformations.scaling(5, 5, 5)
     c = Transformations.translation(10, 5, 7)
     # rotate first
     p2 = Matrix.multiply_tuple(a, p)
     self.assertEqual(p2, Point(1, -1, 0))
     # apply scaling
     p3 = Matrix.multiply_tuple(b, p2)
     self.assertEqual(p3, Point(5, -5, 0))
     # apply translation
     p4 = Matrix.multiply_tuple(c, p3)
     self.assertEqual(p4, Point(15, 0, 7))
Exemple #27
0
class Clock:

    if __name__ == '__main__':
        canvas_size = 300
        canvas = Canvas(canvas_size, canvas_size)
        color = Color(1, 1, 1)
        radius = canvas_size * 3 / 8
        scale = Transformations.scaling(radius, radius, 0)
        origin = Point(0, 0, 0)
        center_translation = Transformations.translation(
            canvas_size / 2, canvas_size / 2, 0)
        center = Matrix.multiply_tuple(center_translation, origin)

        hour = Point(0, 1, 0)  # twelve
        for _ in range(12):
            scaled_hour = Matrix.multiply_tuple(scale, hour)
            positioned_hour = scaled_hour + center
            canvas.write_pixel(round(positioned_hour.x),
                               round(canvas.height - positioned_hour.y), color)
            hour_rotation = Transformations.rotation_z(math.pi / 6)
            hour = Matrix.multiply_tuple(hour_rotation, hour)

        canvas.canvas_to_ppm()
from sphere import Sphere
from transformations import Transformations
from tuple import Point, Vector
from world import World

if __name__ == '__main__':
    # The floor is an extremely flattened sphere with a matte texture
    floor = Sphere()
    floor.transform = Transformations.scaling(10, 0.1, 10)
    floor.material = Material()
    floor.material.color = Color(1, 0.9, 0.9)
    floor.material.specular = 0

    # The wall on the left has the same scale and color as the floor, but is also rotated and translated into place
    left_wall = Sphere()
    left_wall.transform = Transformations.translation(0, 0, 5)
    left_wall.transform = left_wall.transform.dot(
        Transformations.rotation_y(-math.pi / 4))
    left_wall.transform = left_wall.transform.dot(
        Transformations.rotation_x(math.pi / 2))
    left_wall.transform = left_wall.transform.dot(
        Transformations.scaling(10, 0.1, 10))
    left_wall.material = floor.material

    # The wall on the right is identical to the left wall, but is rotated the opposite direction in y
    right_wall = Sphere()
    right_wall.transform = Transformations.translation(0, 0, 5)
    right_wall.transform = right_wall.transform.dot(
        Transformations.rotation_y(math.pi / 4))
    right_wall.transform = right_wall.transform.dot(
        Transformations.rotation_x(math.pi / 2))
Exemple #29
0
 def test_intersect_translated_sphere(self):
     r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
     s = Sphere()
     s.transform = Transformations.translation(5, 0, 0)
     xs = s.intersect(r)
     self.assertEqual(len(xs), 0)
Exemple #30
0
 def test_normal_translated_sphere(self):
     s = Sphere()
     s.transform = Transformations.translation(0, 1, 0)
     n = s.normal_at(Point(0, 1.70711, -0.70711))
     self.assertEqual(n, Vector(0, 0.70711, -0.70711))