def test_mixed_hit():
    s = Sphere()
    i1 = Intersection(-1, s)
    i2 = Intersection(1, s)
    xs = Intersections(i1, i2)
    i = xs.hit()
    assert i == i2
def test_positive_hit():
    s = Sphere()
    i1 = Intersection(1, s)
    i2 = Intersection(2, s)
    xs = Intersections(i1, i2)
    i = xs.hit()
    assert i == i1
def test_negative_hit():
    s = Sphere()
    i1 = Intersection(-2, s)
    i2 = Intersection(-1, s)
    xs = Intersections(i1, i2)
    i = xs.hit()
    assert i is None
def test_assert_lowest_hit():
    s = Sphere()
    i1 = Intersection(5, s)
    i2 = Intersection(7, s)
    i3 = Intersection(-3, s)
    i4 = Intersection(2, s)
    xs = Intersections(i1, i2, i3, i4)
    i = xs.hit()
    assert i == i4
Beispiel #5
0
    def local_intersect(self, ray: Ray):
        a = ray.direction.x**2 + ray.direction.z**2
        if abs(a) < EPSILON:
            xs = Intersections()
            self.intersect_caps(ray, xs)
            return xs

        b = 2 * ray.origin.x * ray.direction.x + 2 * ray.origin.z * ray.direction.z
        c = ray.origin.x**2 + ray.origin.z**2 - 1
        disc = b**2 - 4 * a * c
        if disc < 0:
            return Intersections()

        t0 = (-b - math.sqrt(disc)) / (2 * a)
        t1 = (-b + math.sqrt(disc)) / (2 * a)

        if t0 > t1:
            t0, t1 = (t1, t0)

        xs = Intersections()

        y0 = ray.origin.y + t0 * ray.direction.y
        if self.minimum < y0 and y0 < self.maximum:
            xs.append(Intersection(t0, self))

        y1 = ray.origin.y + t1 * ray.direction.y
        if self.minimum < y1 and y1 < self.maximum:
            xs.append(Intersection(t1, self))

        self.intersect_caps(ray, xs)
        return xs
Beispiel #6
0
 def local_intersect(self, ray: Ray):
     xtmin, xtmax = check_axis(ray.origin.x, ray.direction.x)
     ytmin, ytmax = check_axis(ray.origin.y, ray.direction.y)
     ztmin, ztmax = check_axis(ray.origin.z, ray.direction.z)
     tmin = max(xtmin, ytmin, ztmin)
     tmax = min(xtmax, ytmax, ztmax)
     if tmin > tmax:
         return Intersections()
     else:
         return Intersections(Intersection(tmin, self),
                              Intersection(tmax, self))
Beispiel #7
0
    def local_intersect(self, ray: Ray):
        obj_to_ray = ray.origin - self.origin
        a = ray.direction.dot(ray.direction)
        b = 2 * ray.direction.dot(obj_to_ray)
        c = obj_to_ray.dot(obj_to_ray) - 1

        discriminant = b**2 - 4 * a * c
        if discriminant < 0:
            return Intersections()

        t1 = (-b - math.sqrt(discriminant)) / (2 * a)
        t2 = (-b + math.sqrt(discriminant)) / (2 * a)
        return Intersections(Intersection(t1, self), Intersection(t2, self))
def test_schlick_perpendicular():
    s = GlassSphere()
    r = Ray(Point(0, 0, 0), Vector(0, 1, 0))
    xs = Intersections(Intersection(-1, s), Intersection(1, s))
    comps = xs[1].prepare_computation(r, xs)
    reflectance = comps.schlick()
    assert equal(reflectance, 0.04)
def test_schlick_small_angle():
    s = GlassSphere()
    r = Ray(Point(0, 0.99, -2), Vector(0, 0, 1))
    xs = Intersections(Intersection(1.8589, s))
    comps = xs[0].prepare_computation(r, xs)
    reflectance = comps.schlick()
    assert equal(reflectance, 0.48873)
def test_aggregate_intersections():
    s = Sphere()
    i1 = Intersection(1, s)
    i2 = Intersection(2, s)
    xs = Intersections(i1, i2)
    assert len(xs) == 2
    assert xs[0].t == 1
    assert xs[1].t == 2
def test_schlick_tir():
    rt2 = math.sqrt(2) / 2
    s = GlassSphere()
    r = Ray(Point(0, 0, rt2), Vector(0, 1, 0))
    xs = Intersections(Intersection(-rt2, s), Intersection(rt2, s))
    comps = xs[1].prepare_computation(r, xs)
    reflectance = comps.schlick()
    assert reflectance == 1.0
Beispiel #12
0
def test_refracted_opaque():
    w = World().default()
    s = w.objects[0]
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    xs = Intersections(Intersection(4, s), Intersection(6, s))
    comps = xs[0].prepare_computation(r, xs)
    c = w.refracted_color(comps, 5)
    assert c == Color(0, 0, 0)
def test_under_point():
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    s = GlassSphere()
    s.set_transform(Translation(0, 0, 1))
    i = Intersection(5, s)
    xs = Intersections(i)
    comps = i.prepare_computation(r, xs)
    assert comps.under_point.z > EPSILON / 2
    assert comps.point.z < comps.under_point.z
Beispiel #14
0
def test_refracted_max_depth():
    w = World().default()
    s = w.objects[0]
    s.material.transparency = 1.0
    s.material.refractive_index = 1.5
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    xs = Intersections(Intersection(4, s), Intersection(6, s))
    comps = xs[0].prepare_computation(r, xs)
    c = w.refracted_color(comps, 0)
    assert c == Color(0, 0, 0)
Beispiel #15
0
    def local_intersect(self, ray: Ray):
        dir_cross_e2 = ray.direction.cross(self.e2)
        det = self.e1.dot(dir_cross_e2)
        if abs(det) < EPSILON:
            return Intersections()

        f = 1.0 / det
        p1_to_origin = ray.origin - self.p1
        u = f * p1_to_origin.dot(dir_cross_e2)
        if u < 0 or u > 1:
            return Intersections()

        origin_cross_e1 = p1_to_origin.cross(self.e1)
        v = f * ray.direction.dot(origin_cross_e1)
        if v < 0 or (u + v) > 1:
            return Intersections()

        t = f * self.e2.dot(origin_cross_e1)
        return Intersections(Intersection(
            t, self))  # BOGUS TO TEST AGAINST POSITIVE
Beispiel #16
0
def test_refracted_total():
    w = World().default()
    s = w.objects[0]
    s.material.transparency = 1.0
    s.material.refractive_index = 1.5
    r = Ray(Point(0, 0, math.sqrt(2) / 2), Vector(0, 1, 0))
    xs = Intersections(
        Intersection(-math.sqrt(2) / 2, s), Intersection(math.sqrt(2) / 2, s)
    )
    comps = xs[1].prepare_computation(r, xs)
    c = w.refracted_color(comps, 5)
    assert c == Color(0, 0, 0)
Beispiel #17
0
 def local_intersect(self, ray: Ray):
     total_xs = Intersections()
     for obj in self.objects:
         xs = obj.intersect(ray)
         total_xs.extend(xs)
     total_xs.sort()
     for x in total_xs:
         print(x)
     return total_xs
Beispiel #18
0
def shade_hit_transparent():
    w = World().default()
    floor = Plane()
    floor.set_transform(Translation(0, -1, 0))
    floor.material.transparency = 0.5
    floor.material.refractive_index = 1.5
    w.objects.append(floor)
    ball = Sphere()
    ball.material.color = Color(1, 0, 0)
    ball.material.ambient = 0.5
    ball.set_transform(Translation(0, -3.5, -0.5))
    w.objects.append(ball)
    r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2))
    xs = Intersections(Intersection(math.sqrt(2), floor))
    comps = xs[0].prepare_computations(r, xs)
    color = w.shade_hit(comps, 5)
    assert color == Color(0.93642, 0.68642, 0.68642)
Beispiel #19
0
def test_refracted_color():
    w = World().default()
    a = w.objects[0]
    a.material.ambient = 1.0
    a.material.pattern = _TestPattern()
    b = w.objects[1]
    b.material.transparency = 1.0
    b.material.refractive_index = 1.5
    r = Ray(Point(0, 0, 0.1), Vector(0, 1, 0))
    xs = Intersections(
        Intersection(-0.9899, a),
        Intersection(-0.4899, b),
        Intersection(0.4899, b),
        Intersection(0.9899, a),
    )
    comps = xs[2].prepare_computation(r, xs)
    c = w.refracted_color(comps, 5)
    print(c)
    assert c == Color(0, 0.99888, 0.04725)
def check_n1_n2(index):
    a = GlassSphere()
    a.set_transform(Scaling(2, 2, 2))
    a.material.refractive_index = 1.5

    b = GlassSphere()
    b.set_transform(Translation(0, 0, -0.25))
    b.material.refractive_index = 2.0

    c = GlassSphere()
    c.set_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),
    )
    comps = xs[index].prepare_computation(r, xs)
    return (comps.n1, comps.n2)
Beispiel #21
0
 def local_intersect(self, ray: Ray):
     if abs(ray.direction.y) < EPSILON:
         return Intersections()
     t = -ray.origin.y / ray.direction.y
     return Intersections(Intersection(t, self))
Beispiel #22
0
 def intersect(self, ray):
     xs = Intersections()
     for obj in self.objects:
         xs.extend(obj.intersect(ray))
     xs.sort()
     return xs