示例#1
0
 def when_convex_mirror_is_constructed(self):
     self.mirror = SphericalMirror(
         placement=self.placement,
         diameter=self.diameter,
         focal_length=-self.focal_length
     )
示例#2
0
class TestSphericalMirror(unittest.TestCase):
    """
    Test SphericalMirror class
    """

    def clean_state(self):
        self.mirror = None
        self.aperture = None
        self.diameter = None
        self.aperture_origin = None
        self.aperture_direction = None
        self.aperture_normal = None
        self.orthogonal_directions = None
        self.placement = None
        self.ray_location = None
        self.orthogonal_direction = None
        self.scale_factor = None
        self.test_ray_distance = None
        self.test_ray = None
        self.initial_wavefront = None
        self.filtered_wavefront = None
        self.test_directions = None
        self.test_direction = None
        self.test_point = None

    def setUp(self):
        self.clean_state()
        self.diameter = 10.0
        self.focal_length = 50.0
        self.aperture_origin = Position.from_xyz((10.0, 20.0, 30.0))
        self.aperture_direction = Direction.from_xyz((1.0, 2.0, 3.0))
        self.aperture_normal = self.aperture_direction.normalized()
        self.placement = Ray(self.aperture_origin, self.aperture_normal)
        self.orthogonal_directions = [
            self.aperture_direction.cross(Direction.right).normalized(),
            self.aperture_direction.cross(Direction.forward).normalized(),
            self.aperture_direction.cross(Direction.backward).normalized(),
        ]
        self.test_directions = [self.aperture_normal.add(
            orthogonal_direction.scale(0.1)).normalized() for orthogonal_direction in self.orthogonal_directions]

    def tearDown(self):
        self.clean_state()

    def test_positive_focal_length_is_concave(self):
        self.when_concave_mirror_is_constructed()
        self.then_mirror_is_concave()

    def when_concave_mirror_is_constructed(self):
        self.mirror = SphericalMirror(
            placement=self.placement,
            diameter=self.diameter,
            focal_length=self.focal_length
        )

    def then_mirror_is_concave(self):
        self.assertFalse(self.mirror.is_convex)
        self.assertTrue(self.mirror.is_concave)

    def test_negative_focal_length_is_concave(self):
        self.when_convex_mirror_is_constructed()
        self.then_mirror_is_convex()

    def when_convex_mirror_is_constructed(self):
        self.mirror = SphericalMirror(
            placement=self.placement,
            diameter=self.diameter,
            focal_length=-self.focal_length
        )

    def then_mirror_is_convex(self):
        self.assertTrue(self.mirror.is_convex)
        self.assertFalse(self.mirror.is_concave)

    def test_spherical_radius_is_correct(self):
        self.when_concave_mirror_is_constructed()
        self.then_spherical_radius_is_twice_focal_length()
        self.when_convex_mirror_is_constructed()
        self.then_spherical_radius_is_twice_focal_length()

    def then_spherical_radius_is_twice_focal_length(self):
        spherical_radius = self.mirror.sphere.radius
        self.assertAlmostEqual(2.0 * math.fabs(self.focal_length), spherical_radius)

    def test_aperture_circle_lies_on_sphere(self):
        self.when_concave_mirror_is_constructed()
        self.then_aperture_circle_lies_on_sphere()
        self.when_convex_mirror_is_constructed()
        self.then_aperture_circle_lies_on_sphere()

    def then_aperture_circle_lies_on_sphere(self):
        for self.orthogonal_direction in self.orthogonal_directions:
            self.when_aperture_circle_point_is_constructed()
            self.then_aperture_circle_point_lies_on_sphere()

    def when_aperture_circle_point_is_constructed(self):
        self.test_direction = self.orthogonal_direction.scale(self.diameter * 0.5)
        self.test_point = self.aperture_origin.add(self.test_direction)

    def then_aperture_circle_point_lies_on_sphere(self):
        actual_elevation = self.mirror.sphere.elevation(self.test_point)
        self.assertAlmostEqual(0.0, actual_elevation)

    def test_rays_from_center_of_sphere_reflect_back(self):
        self.when_concave_mirror_is_constructed()
        self.when_test_rays_are_positioned_at_sphere_center()
        self.then_test_rays_reflect_back()

    def when_test_rays_are_positioned_at_sphere_center(self):
        self.test_center_position = self.mirror.sphere.center_position
        self.when_test_rays_are_constructed()

    def when_test_rays_are_constructed(self):
        self.test_rays = [Ray(self.test_center_position, test_direction)
                          for test_direction in self.test_directions]

    def then_test_rays_reflect_back(self):
        for self.test_ray in self.test_rays:
            self.when_test_ray_is_reflected()
            self.then_reflected_ray_is_opposite_of_test_ray()

    def when_test_ray_is_reflected(self):
        self.reflected_ray = self.mirror.reflect(self.test_ray)

    def then_reflected_ray_is_opposite_of_test_ray(self):
        dotProduct = vector_dot_product(self.test_ray.direction.xyz, self.reflected_ray.direction.xyz)
        self.assertAlmostEqual(-1.0, dotProduct)

    def test_rays_from_focal_point_of_sphere_reflect_parallel(self):
        self.when_concave_mirror_is_constructed()
        self.when_test_rays_are_positioned_at_focal_point()
        self.then_test_rays_reflect_parallel()

    def when_test_rays_are_positioned_at_focal_point(self):
        self.test_center_position = self.mirror.sphere.center_position.add(
            self.aperture_normal.scale(self.focal_length)
        )
        self.when_test_rays_are_constructed()

    def then_test_rays_reflect_parallel(self):
        for self.test_ray in self.test_rays:
            self.when_test_ray_is_reflected()
            self.then_reflected_ray_is_opposite_of_aperture_normal()

    def then_reflected_ray_is_opposite_of_aperture_normal(self):
        dotProduct = vector_dot_product(self.aperture_normal.xyz, self.reflected_ray.direction.xyz)
        self.assertAlmostEqual(-1.0, dotProduct)