Пример #1
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}")
Пример #2
0
def test_sphere_intersection_scaled():
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = Sphere()
    s.set_transform(scaling(2, 2, 2))
    x = r.intersects(s)
    assert len(x) == 2
    assert x[0].t == 3
    assert x[1].t == 7
Пример #3
0
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)
Пример #4
0
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]
Пример #5
0
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]
Пример #6
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")
Пример #7
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
Пример #8
0
def test_sphere_normal_at_scaled():
    s = Sphere()
    s.set_transform(scaling(1, 0.5, 1))
    n = s.normal_at(Point(0, sqrt(2) / 2, -sqrt(2) / 2))
    assert n == Vector(0, 0.9701425001453319, -0.24253562503633297)
Пример #9
0
def test_scale():
    r = Ray(Point(1, 2, 3), Vector(0, 1, 0))
    m = scaling(2, 3, 4)
    r2 = r.transform(m)
    assert r2.origin == Point(2, 6, 12)
    assert r2.direction == Vector(0, 3, 0)
Пример #10
0
def test_reflection():
    t = scaling(-1, 1, 1)
    p = Point(2, 3, 4)

    assert t * p == Point(-2, 3, 4)
Пример #11
0
def test_scaling_inverse():
    t = scaling(2, 3, 4)
    inv = t.inv
    v = Vector(-4, 6, 8)

    assert inv * v == Vector(-2, 2, 2)
Пример #12
0
def test_scaling_vector():
    t = scaling(2, 3, 4)
    p = Vector(-4, 6, 8)

    assert t * p == Vector(-8, 18, 32)
Пример #13
0
def test_scaling_point():
    t = scaling(2, 3, 4)
    p = Point(-4, 6, 8)
    assert t * p == Point(-8, 18, 32)
Пример #14
0
from math import pi

from src.canvas import Canvas
from src.color import Color
from src.primitives import Sphere
from src.ray import Ray
from src.transformations import scaling, rotation_z
from src.tupl import Point

s = Sphere()
t = rotation_z(pi / 4) @ scaling(0.5, 1, 1)
s.set_transform(t)
r_origin = Point(0, 0, -5)
wall_z = 10
wall_size = 7

N = 100
c = Canvas(N, N)
pixel_size = wall_size / N
half = wall_size / 2
red = Color(255, 0, 0)

for y in range(c.height):
    world_y = half - pixel_size * y
    for x in range(c.width):
        world_x = -half + pixel_size * x
        position = Point(world_x, world_y, wall_z)
        r = Ray(r_origin, (position - r_origin).normalize())
        X = r.intersects(s)
        if X.hit is not None:
            c.write_pixel(x, y, red)
Пример #15
0
def assign_scaling(context, var, x, y, z):
    context.variables[var] = scaling(x, y, z)