示例#1
0
    def testTransformation(self):
        sphere = Sphere(transformation=translation(Vec(10.0, 0.0, 0.0)))

        ray1 = Ray(origin=Point(10, 0, 2), dir=-VEC_Z)
        intersection1 = sphere.ray_intersection(ray1)
        assert intersection1
        assert HitRecord(
            world_point=Point(10.0, 0.0, 1.0),
            normal=Normal(0.0, 0.0, 1.0),
            surface_point=Vec2d(0.0, 0.0),
            t=1.0,
            ray=ray1,
            material=sphere.material,
        ).is_close(intersection1)

        ray2 = Ray(origin=Point(13, 0, 0), dir=-VEC_X)
        intersection2 = sphere.ray_intersection(ray2)
        assert intersection2
        assert HitRecord(
            world_point=Point(11.0, 0.0, 0.0),
            normal=Normal(1.0, 0.0, 0.0),
            surface_point=Vec2d(0.0, 0.5),
            t=2.0,
            ray=ray2,
            material=sphere.material,
        ).is_close(intersection2)

        # Check if the sphere failed to move by trying to hit the untransformed shape
        assert not sphere.ray_intersection(
            Ray(origin=Point(0, 0, 2), dir=-VEC_Z))

        # Check if the *inverse* transformation was wrongly applied
        assert not sphere.ray_intersection(
            Ray(origin=Point(-10, 0, 0), dir=-VEC_Z))
示例#2
0
    def testHit(self):
        sphere = Sphere()

        ray1 = Ray(origin=Point(0, 0, 2), dir=-VEC_Z)
        intersection1 = sphere.ray_intersection(ray1)
        assert intersection1
        assert HitRecord(
            world_point=Point(0.0, 0.0, 1.0),
            normal=Normal(0.0, 0.0, 1.0),
            surface_point=Vec2d(0.0, 0.0),
            t=1.0,
            ray=ray1,
            material=sphere.material,
        ).is_close(intersection1)

        ray2 = Ray(origin=Point(3, 0, 0), dir=-VEC_X)
        intersection2 = sphere.ray_intersection(ray2)
        assert intersection2
        assert HitRecord(
            world_point=Point(1.0, 0.0, 0.0),
            normal=Normal(1.0, 0.0, 0.0),
            surface_point=Vec2d(0.0, 0.5),
            t=2.0,
            ray=ray2,
            material=sphere.material,
        ).is_close(intersection2)

        assert not sphere.ray_intersection(
            Ray(origin=Point(0, 10, 2), dir=-VEC_Z))
示例#3
0
    def testNormals(self):
        sphere = Sphere(transformation=scaling(Vec(2.0, 1.0, 1.0)))

        ray = Ray(origin=Point(1.0, 1.0, 0.0), dir=Vec(-1.0, -1.0))
        intersection = sphere.ray_intersection(ray)
        # We normalize "intersection.normal", as we are not interested in its length
        assert intersection.normal.normalize().is_close(
            Normal(1.0, 4.0, 0.0).normalize())
示例#4
0
    def testNormalDirection(self):
        # Scaling a sphere by -1 keeps the sphere the same but reverses its
        # reference frame
        sphere = Sphere(transformation=scaling(Vec(-1.0, -1.0, -1.0)))

        ray = Ray(origin=Point(0.0, 2.0, 0.0), dir=-VEC_Y)
        intersection = sphere.ray_intersection(ray)
        # We normalize "intersection.normal", as we are not interested in its length
        assert intersection.normal.normalize().is_close(
            Normal(0.0, 1.0, 0.0).normalize())
示例#5
0
    def testInnerHit(self):
        sphere = Sphere()

        ray = Ray(origin=Point(0, 0, 0), dir=VEC_X)
        intersection = sphere.ray_intersection(ray)
        assert intersection
        assert HitRecord(
            world_point=Point(1.0, 0.0, 0.0),
            normal=Normal(-1.0, 0.0, 0.0),
            surface_point=Vec2d(0.0, 0.5),
            t=1.0,
            ray=ray,
        ).is_close(intersection)
示例#6
0
    def testUVCoordinates(self):
        sphere = Sphere()

        # The first four rays hit the unit sphere at the
        # points P1, P2, P3, and P4.
        #
        #                    ^ y
        #                    | P2
        #              , - ~ * ~ - ,
        #          , '       |       ' ,
        #        ,           |           ,
        #       ,            |            ,
        #      ,             |             , P1
        # -----*-------------+-------------*---------> x
        #   P3 ,             |             ,
        #       ,            |            ,
        #        ,           |           ,
        #          ,         |        , '
        #            ' - , _ * _ ,  '
        #                    | P4
        #
        # P5 and P6 are aligned along the x axis and are displaced
        # along z (ray5 in the positive direction, ray6 in the negative
        # direction).

        ray1 = Ray(origin=Point(2.0, 0.0, 0.0), dir=-VEC_X)
        assert sphere.ray_intersection(ray1).surface_point.is_close(
            Vec2d(0.0, 0.5))

        ray2 = Ray(origin=Point(0.0, 2.0, 0.0), dir=-VEC_Y)
        assert sphere.ray_intersection(ray2).surface_point.is_close(
            Vec2d(0.25, 0.5))

        ray3 = Ray(origin=Point(-2.0, 0.0, 0.0), dir=VEC_X)
        assert sphere.ray_intersection(ray3).surface_point.is_close(
            Vec2d(0.5, 0.5))

        ray4 = Ray(origin=Point(0.0, -2.0, 0.0), dir=VEC_Y)
        assert sphere.ray_intersection(ray4).surface_point.is_close(
            Vec2d(0.75, 0.5))

        ray5 = Ray(origin=Point(2.0, 0.0, 0.5), dir=-VEC_X)
        assert sphere.ray_intersection(ray5).surface_point.is_close(
            Vec2d(0.0, 1 / 3))

        ray6 = Ray(origin=Point(2.0, 0.0, -0.5), dir=-VEC_X)
        assert sphere.ray_intersection(ray6).surface_point.is_close(
            Vec2d(0.0, 2 / 3))