Exemple #1
0
    def __init__(self, p1, p2, p3, n1=None, n2=None, n3=None):
        super().__init__()
        self.p1 = p1
        self.p2 = p2
        self.p3 = p3
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3

        self.smoothed = False

        # pre-compute edge vectors
        self.e1 = subtract(p2, p1)
        self.e2 = subtract(p3, p1)

        # pre-compute normal
        self.normal = normalize(cross(self.e2, self.e1))
Exemple #2
0
    def is_shadowed(self, light_position, hit_point):
        vec = subtract(light_position, hit_point)
        distance = magnitude(vec)
        direction = normalize(vec)

        ray = Ray(hit_point, direction)
        intersections = self.intersect(ray)
        hit_intersection = shadow_hit(intersections)
        return hit_intersection is not None and hit_intersection.t < distance
Exemple #3
0
    def ray_for_pixel(self, pixel_x, pixel_y):
        xoffset = (pixel_x + 0.5) * self.pixel_size
        yoffset = (pixel_y + 0.5) * self.pixel_size

        world_x = self.half_width - xoffset
        world_y = self.half_height - yoffset

        pixel = multiply_tuple(self.__inverse_transform,
                               point(world_x, world_y, -1))
        origin = multiply_tuple(self.__inverse_transform, point(0, 0, 0))
        direction = normalize(subtract(pixel, origin))

        return Ray(origin, direction)
Exemple #4
0
    def local_intersect(self, local_ray):
        sphere_to_ray = subtract(local_ray.origin, point(0, 0, 0))

        a = dot(local_ray.direction, local_ray.direction)
        b = 2 * dot(local_ray.direction, sphere_to_ray)
        c = dot(sphere_to_ray, sphere_to_ray) - 1

        discriminant = b**2 - 4 * a * c

        if discriminant < 0:
            return []

        t1 = (-b - sqrt(discriminant)) / (2 * a)
        t2 = (-b + sqrt(discriminant)) / (2 * a)

        i1 = Intersection(t1, self)
        i2 = Intersection(t2, self)
        return [i1, i2]
def main():
    canvas_pixels = 500
    canvas = Canvas(canvas_pixels, canvas_pixels)
    shape = Sphere()

    # assign material
    shape.material = Material()
    shape.material.color = color(1, 0.2, 1)

    light_position = point(-10, 10, -10)
    light_color = color(1, 1, 1)
    light = PointLight(light_position, light_color)

    ray_origin = point(0, 0, -5)
    wall_z = 10
    wall_size = 7.0

    pixel_size = wall_size / canvas_pixels
    half = wall_size / 2

    for y in range(canvas_pixels):
        world_y = half - pixel_size * y

        for x in range(canvas_pixels):
            world_x = -half + pixel_size * x

            pos = point(world_x, world_y, wall_z)

            r = Ray(ray_origin, normalize(subtract(pos, ray_origin)))
            xs = shape.intersect(r)

            shape_hit = hit(xs)
            if shape_hit is not None:
                hit_point = r.position_at(shape_hit.t)
                normal = shape_hit.object.normal_at(hit_point)
                eye = negate(r.direction)
                px_color = lighting(shape_hit.object.material,
                                    shape_hit.object, light, hit_point, eye,
                                    normal)
                canvas.set_pixel(x, y, px_color)

    with open('render_phong_sphere.ppm', 'w') as out_file:
        out_file.write(canvas.to_ppm())
Exemple #6
0
def main():
    canvas_pixels = 400
    canvas = Canvas(canvas_pixels, canvas_pixels)
    red = color(1, 0, 0)
    shape = Sphere()

    # shrink it along the y axis
    #shape.set_transform(scaling(1, 0.5, 1))
    # shrink it along the x axis
    #shape.set_transform(scaling(0.5, 1, 1))
    # shrink it, and rotate it!
    # shape.set_transform(multiply_matrix(rotation_z(pi / 4), scaling(0.5, 1,
    #                                                                 1)))
    # shrink it, and skew it!
    # shape.set_transform(
    #     multiply_matrix(shearing(1, 0, 0, 0, 0, 0), scaling(0.5, 1, 1)))

    ray_origin = point(0, 0, -5)
    wall_z = 10
    wall_size = 7.0

    pixel_size = wall_size / canvas_pixels
    half = wall_size / 2

    for y in range(canvas_pixels):
        world_y = half - pixel_size * y

        for x in range(canvas_pixels):
            world_x = -half + pixel_size * x

            pos = point(world_x, world_y, wall_z)

            r = Ray(ray_origin, normalize(subtract(pos, ray_origin)))
            xs = shape.intersect(r)

            if hit(xs) is not None:
                canvas.set_pixel(x, y, red)

    with open('render_sphere.ppm', 'w') as out_file:
        out_file.write(canvas.to_ppm())
Exemple #7
0
    def local_intersect(self, local_ray):
        dir_cross_e2 = cross(local_ray.direction, self.e2)
        determinant = dot(self.e1, dir_cross_e2)
        if abs(determinant) < self.EPSILON:
            return []

        f = 1.0 / determinant
        p1_to_origin = subtract(local_ray.origin, self.p1)
        u = f * dot(p1_to_origin, dir_cross_e2)
        if u < 0.0 or u > 1.0:
            return []

        origin_cross_e1 = cross(p1_to_origin, self.e1)
        v = f * dot(local_ray.direction, origin_cross_e1)
        if v < 0.0 or (u + v) > 1.0:
            return []

        t = f * dot(self.e2, origin_cross_e1)

        if self.smoothed:
            return [Intersection(t, self, u, v)]

        return [Intersection(t, self)]
Exemple #8
0
    def refracted_color(self, hit, remaining=5):
        if remaining <= 0:
            return color(0, 0, 0)

        if hit.object.material.transparency == 0.0:
            return color(0, 0, 0)

        n_ratio = hit.n1 / hit.n2
        cos_i = dot(hit.eyev, hit.normalv)
        sin2_t = n_ratio**2 * (1 - cos_i**2)

        if sin2_t > 1.0:
            return color(0, 0, 0)

        cos_t = sqrt(1.0 - sin2_t)

        direction = subtract(multiply(hit.normalv, (n_ratio * cos_i - cos_t)),
                             multiply(hit.eyev, n_ratio))

        refract_ray = Ray(hit.under_point, direction)

        return multiply(self.color_at(refract_ray, remaining - 1),
                        hit.object.material.transparency)
def step_impl(context):
    actual = subtract(context.c1, context.c2)
    assert_tuple(actual, color(0.2, 0.5, 0.5))
def step_create_eye_vector_v1_from_eye_to_p(context):
    context.v1 = normalize(subtract(context.eye, context.p))
Exemple #11
0
 def pattern_at(self, point):
     distance = subtract(self.color_b, self.color_a)
     fraction = point[0] - floor(point[0])
     return add(self.color_a, multiply(distance, fraction))
Exemple #12
0
 def local_normal_at(self, local_point, hit=None):
     return subtract(local_point, point(0, 0, 0))