Пример #1
0
def run() -> None:
    room = create_room()
    objects = create_objects()
    world = World()
    world.light = PointLight(point(-10, 10, -10), Color(1, 1, 1))
    world.objects.extend(room)
    world.objects.extend(objects)
    camera = Camera(400, 200, math.pi / 3)
    camera.transform = view_transform(point(0, 1.5, -5), point(0, 1, 0),
                                      vector(0, 1, 0))
    canvas = camera.render(world)
    PPM(canvas).save_to_file("scene.ppm")
Пример #2
0
def canvas_to_world(canvas_coordinate: Point) -> Point:
    pixel_size = WALL_SIZE / CANVAS_SIZE

    x = pixel_size * canvas_coordinate.x - WALL_SIZE / 2
    y = -(pixel_size * canvas_coordinate.y - WALL_SIZE / 2)
    z = WALL_Z
    return point(x, y, z)
Пример #3
0
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}")
Пример #4
0
 def normal_at(self, world_point: Point) -> Vector:
     transformer = inverse(self.transform)
     object_point = transformer * world_point
     object_normal = object_point - point(0, 0, 0)
     world_normal = transpose(transformer) * object_normal
     world_normal = vector(world_normal.x, world_normal.y,
                           world_normal.z)  # set w to 0
     return normalize(world_normal)
Пример #5
0
def check_attribute_point(context, var, att, tuple_type, x, y, z):
    if tuple_type == "point":
        expected = point(x, y, z)
    elif tuple_type == "vector":
        expected = vector(x, y, z)
    elif tuple_type == "color":
        expected = Color(x, y, z)  # type: ignore
    else:
        raise ValueError(f"tuple type '{tuple_type}' not recognized")

    my_variable = context.variables[var]
    assert (getattr(
        my_variable,
        att) == expected), f"{getattr(my_variable, att)} == {expected}"
Пример #6
0
def run() -> None:
    # Eye is at (0,0, 5)
    origin = point(0, 0, 5)

    shape = Sphere()
    # shape.set_transform(scaling(0.5, 1, 1))
    shape.material.color = Color(0.9, 0.2, 1)

    light = PointLight(point(-10, 10, 10), Color(1, 1, 1))
    canvas = Canvas(CANVAS_SIZE, CANVAS_SIZE)

    for i in range(CANVAS_SIZE):
        for j in range(CANVAS_SIZE):
            target = canvas_to_world(point(i, j, 0))
            ray = Ray(origin, normalize(target - origin))
            hit = find_hit(shape.intersect(ray))
            if hit is not None:
                hit_point = position(ray, hit.t)
                normal = hit.shape.normal_at(hit_point)
                pixel_color = lighting(hit.shape.material, light, hit_point,
                                       -ray.direction, normal)
                canvas.write_pixel(i, j, pixel_color)

    PPM(canvas).save_to_file("sphere.ppm")
Пример #7
0
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")
Пример #8
0
def default_world() -> World:
    """A default world with 2 spheres and a light"""
    sphere_1 = Sphere()
    sphere_1.material = Material()
    sphere_1.material.color = Color(0.8, 1.0, 0.6)
    sphere_1.material.diffuse = 0.7
    sphere_1.material.specular = 0.2
    sphere_2 = Sphere()
    sphere_2.transform = scaling(0.5, 0.5, 0.5)

    world = World()
    world.light = PointLight(point(-10, 10, -10), Color(1, 1, 1))
    world.objects.append(sphere_1)
    world.objects.append(sphere_2)

    return world
Пример #9
0
def check_position(context, var, t, x, y, z):
    ray = context.variables[var]
    expected = point(x, y, z)
    assert position(ray, t) == expected
Пример #10
0
def assign_ray_inline(context, var, px, py, pz, vx, vy, vz):
    origin = point(px, py, pz)
    direction = vector(vx, vy, vz)
    context.variables[var] = Ray(origin, direction)
Пример #11
0
 def __init__(self) -> None:
     self.origin = point(0, 0, 0)
     self.radius = 1.0
     self.transform = identity(4)
     self.material = Material()
Пример #12
0
def assign_normal(context, var, obj_var, x, y, z):
    shape = context.variables[obj_var]
    context.variables[var] = shape.normal_at(point(x, y, z))
Пример #13
0
def assign_point(context, var, x, y, z):
    context.variables[var] = point(x, y, z)
Пример #14
0
def assign_light_inline(context, var, x, y, z, r, g, b):
    context.variables[var] = PointLight(point(x, y, z), Color(r, g, b))