def test_multiplying_by_the_inverse_of_a_scaling_matrix(): # Given transform = scaling(2, 3, 4) inv = transform.inverse() v = Vector(-4, 6, 8) # Then assert inv * v == Vector(-2, 2, 2)
def test_scaling_a_ray(): # Given r = Ray(Point(1, 2, 3), Vector(0, 1, 0)) m = scaling(2, 3, 4) # When r2 = r.transform(m) # Then assert r2.origin == Point(2, 6, 12) assert r2.direction == Vector(0, 3, 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_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)
def test_a_view_transformation_matrix_looking_in_positive_z_direction(): # Given f = Point(0, 0, 0) to = Point(0, 0, 1) up = Vector(0, 1, 0) # When t = view_transform(f, to, up) # Then assert t == scaling(-1, 1, -1)
def test_intersecting_a_scaled_shape_with_a_ray(): # Given r = Ray(Point(0, 0, -5), Vector(0, 0, 1)) s = MockShape() # When s.transform = scaling(2, 2, 2) _ = s.intersect(r) # Then assert s.saved_ray.origin == Point(0, 0, -2.5) assert s.saved_ray.direction == Vector(0, 0, 0.5)
def test_chained_transformations_must_be_applied_in_reverse_order(): # Given p = Point(1, 0, 1) A = rotation_x(pi / 2) B = scaling(5, 5, 5) C = translation(10, 5, 7) # When T = C * B * A # Then assert T * p == Point(15, 0, 7)
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_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
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
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_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_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)
def test_finding_n1_and_n2_at_various_intersections(): # Given A = glass_sphere() A.transform = scaling(2, 2, 2) A.material.refractive_index = 1.5 B = glass_sphere() B.transform = translation(0, 0, -0.25) B.material.refractive_index = 2.0 C = glass_sphere() C.transform = translation(0, 0, 0.25) C.material.refractive_index = 2.5 r = Ray(Point(0, 0, -4), Vector(0, 0, 1)) xs = Intersections(Intersection(2, A), Intersection(2.75, B), Intersection(3.25, C), Intersection(4.75, B), Intersection(5.25, C), Intersection(6, A)) EXAMPLES = [ { 'n1': 1.0, 'n2': 1.5 }, # index: 0 { 'n1': 1.5, 'n2': 2.0 }, # index: 1 { 'n1': 2.0, 'n2': 2.5 }, # index: 2 { 'n1': 2.5, 'n2': 2.5 }, # index: 3 { 'n1': 2.5, 'n2': 1.5 }, # index: 4 { 'n1': 1.5, 'n2': 1.0 }, # index: 5 ] for index in range(len(EXAMPLES)): # When comps = xs[index].prepare_computations(r, xs=xs) # Then assert comps.n1 == EXAMPLES[index]['n1'] assert comps.n2 == EXAMPLES[index]['n2']
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)
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_individual_transformations_are_applied_in_sequence(): # Given p = Point(1, 0, 1) A = rotation_x(pi / 2) B = scaling(5, 5, 5) C = translation(10, 5, 7) # apply rotation first # When p2 = A * p # Then assert p2 == Point(1, -1, 0) # then apply scaling # When p3 = B * p2 # Then assert p3 == Point(5, -5, 0) # then apply translation # When p4 = C * p3 # Then assert p4 == Point(15, 0, 7)
def test_reflection_is_scaling_by_a_negative_value(): # Given transform = scaling(-1, 1, 1) p = Point(2, 3, 4) # Then assert transform * p == Point(-2, 3, 4)
def test_a_scaling_matrix_applied_to_a_vector(): # Given tranform = scaling(2, 3, 4) v = Vector(-4, 6, 8) # Then assert tranform * v == Vector(-8, 18, 32)
def test_scaling_matrix_applied_to_a_point(): # Given trasform = scaling(2, 3, 4) p = Point(-4, 6, 8) # Then assert trasform * p == Point(-8, 18, 32)
from raytracerchallenge_python.tuple import Color, Point, Vector from raytracerchallenge_python.material import Material from raytracerchallenge_python.sphere import Sphere, glass_sphere from raytracerchallenge_python.plane import Plane from raytracerchallenge_python.cube import Cube # from raytracerchallenge_python.stripe_pattern import StripePattern # from raytracerchallenge_python.checkers_pattern import CheckersPattern # from raytracerchallenge_python.ring_pattern import RingPattern if __name__ == "__main__": # pattern = StripePattern(Color(1, 0, 0), Color(1, 1, 1)) # pattern = CheckersPattern(Color(1, 0, 0), Color(1, 1, 1)) pattern = GradientPattern(Color(1, 0, 0), Color(1, 1, 1)) # pattern = RingPattern(Color(1, 0, 0), Color(1, 1, 1)) pattern.transform = scaling(0.2, 0.2, 0.2) floor = Plane() floor.material = Material() floor.material.color = Color(1, 0.9, 0.9) # floor.material.pattern = pattern backdrop = Plane() backdrop.transform = \ rotation_y(pi / 3) * translation(0, 0, 5) * rotation_x(pi / 2) backdrop2 = Plane() backdrop2.transform = \ rotation_y(-pi / 3) * translation(0, 0, 5) * rotation_x(pi / 2) middle = Sphere()