def run() -> None: STEPS = 180 SIZE = 600 MIDDLE = SIZE // 2 canvas = Canvas(SIZE, SIZE) color = Color(1, 0, 0) color_increment = Color(0, 0, 1.0 / STEPS) position = point(0, 1, 0) rotate = rotation_z(-2 * math.pi / STEPS) translate = translation(MIDDLE, MIDDLE, 0) scale = scaling(SIZE // 3, SIZE // 3, 1) for i in range(STEPS): canvas_position = translate * scale * position assert isinstance(canvas_position, Point) canvas.write_pixel( int(round(canvas_position.x)), SIZE - int(round(canvas_position.y)), color, ) position = rotate * position color += color_increment ppm = PPM(canvas) file_name = "clocks.ppm" ppm.save_to_file(file_name) print(f"Output stored to {file_name}")
def test_transformation_chain(): p = Point(1, 0, 1) A = rotation_x(pi / 2) B = scaling(5, 5, 5) C = translation(10, 5, 7) T = C @ B @ A assert T * p == Point(15, 0, 7)
def create_room() -> List[Sphere]: floor = Sphere() floor.transform = scaling(10, 0.01, 10) floor.material.color = Color(1, 0.9, 0.9) floor.material.specular = 0 left_wall = Sphere() left_wall.transform = (translation(0, 0, 5) * rotation_y(-math.pi / 4) * rotation_x(math.pi / 2) * scaling(10, 0.01, 10)) left_wall.material = floor.material right_wall = Sphere() right_wall.transform = (translation(0, 0, 5) * rotation_y(math.pi / 4) * rotation_x(math.pi / 2) * scaling(10, 0.01, 10)) right_wall.material = floor.material return [floor, left_wall, right_wall]
def create_objects() -> List[Sphere]: middle = Sphere() middle.transform = translation(-0.5, 1, 0.5) middle.material.color = Color(0.1, 1, 0.5) middle.material.diffuse = 0.7 middle.material.specular = 0.3 right = Sphere() right.transform = translation(1.5, 0.5, -0.5) * scaling(0.5, 0.5, 0.5) right.material.color = Color(0.5, 1, 0.1) right.material.diffuse = 0.7 right.material.specular = 0.3 left = Sphere() left.transform = translation(-1.5, 0.33, -0.75) * scaling(0.33, 0.33, 0.33) left.material.color = Color(1, 0.8, 0.1) left.material.diffuse = 0.7 left.material.specular = 0.3 return [middle, right, left]
def create_structure( structure_type: str, x: float, y: float, z: float ) -> Union[Tuple, Color, Matrix]: if structure_type == "vector": return vector(x, y, z) elif structure_type == "point": return point(x, y, z) elif structure_type == "color": return Color(x, y, z) elif structure_type == "scaling": return scaling(x, y, z) elif structure_type == "translation": return translation(x, y, z) else: raise NotImplementedError(f"structure type '{structure_type}' not recognized")
def test_sphere_normal_at_translate(): s = Sphere() s.set_transform(translation(0, 1, 0)) n = s.normal_at(Point(0, 1.70711, -0.70711)) assert n == Vector(0, 0.7071067811865475, -0.7071067811865476)
def test_sphere_intersection_translate(): r = Ray(Point(0, 0, -5), Vector(0, 0, 1)) s = Sphere() s.set_transform(translation(5, 0, 0)) x = r.intersects(s) assert len(x) == 0
def test_sphere_translate(): s = Sphere() t = translation(2, 3, 4) s.set_transform(t) assert s.transform == t
def test_translate(): r = Ray(Point(1, 2, 3), Vector(0, 1, 0)) m = translation(3, 4, 5) r2 = r.transform(m) assert r2.origin == Point(4, 6, 8) assert r2.direction == Vector(0, 1, 0)
def test_translation(): t = translation(5, -3, 2) p = Point(-3, 4, 5) assert t * p == Point(2, 1, 7)
def test_translation_vector_invariance(): t = translation(5, -3, 2) v = Vector(-3, 4, 5) assert t * v == v
def test_translation_inverse(): t = translation(5, -3, 2) inv = t.inv p = Point(-3, 4, 5) assert inv * p == Point(-8, 7, 3)
def assign_translation(context, var, x, y, z): context.variables[var] = translation(x, y, z)