Exemple #1
0
 def setUp(self):
     self.clean_state()
     self.vector = (2.0, 3.0, 4.0)
     vector_length = vector_norm(self.vector)
     self.unit_vector = tuple(component / vector_length for component in self.vector)
     self.position = Position.from_xyz((10.0, 20.0, 30.0))
     self.direction = Direction.from_xyz(self.vector)
     self.unit_direction = Direction.from_xyz(self.unit_vector)
     self.ray = Ray(self.position, self.direction)
     self.unit_ray = Ray(self.position, self.unit_direction)
     self.other_position = Position.from_xyz((-9.0, -88.0, 12.34))
     self.other_direction = Direction.from_xyz((19.0, 8.0, -0.03))
     self.other_ray = Ray(self.other_position, self.other_direction)
     offset = self.position.dot(self.unit_direction)
     plane_projector = (-offset,) + self.unit_vector
     self.plane = Plane(plane_projector)
     self.orthogonal_directions = [
         Direction.from_xyz((0.2, 0.2, -0.25)),
         Direction.from_xyz((-7.0, 2.0, 2.0))
     ]
     self.orthogonal_rays = [Ray(self.position, direction)
                             for direction in self.orthogonal_directions]
Exemple #2
0
 def when_sphere_intersects_ray_through_interior_point(self):
     self.test_ray = Ray.from_origin_endpoint(self.starting_point, self.interior_point)
Exemple #3
0
class TestPlane(unittest.TestCase):
    def clean_state(self):
        self.vector = None
        self.unit_vector = None
        self.position = None
        self.direction = None
        self.unit_direction = None
        self.ray = None
        self.plane = None
        self.orthogonal_directions = None
        self.orthogonal_rays = None
        self.other_position = None
        self.other_direction = None
        self.other_ray = None
        self.intersect_point = None

    def setUp(self):
        self.clean_state()
        self.vector = (2.0, 3.0, 4.0)
        vector_length = vector_norm(self.vector)
        self.unit_vector = tuple(component / vector_length for component in self.vector)
        self.position = Position.from_xyz((10.0, 20.0, 30.0))
        self.direction = Direction.from_xyz(self.vector)
        self.unit_direction = Direction.from_xyz(self.unit_vector)
        self.ray = Ray(self.position, self.direction)
        self.unit_ray = Ray(self.position, self.unit_direction)
        self.other_position = Position.from_xyz((-9.0, -88.0, 12.34))
        self.other_direction = Direction.from_xyz((19.0, 8.0, -0.03))
        self.other_ray = Ray(self.other_position, self.other_direction)
        offset = self.position.dot(self.unit_direction)
        plane_projector = (-offset,) + self.unit_vector
        self.plane = Plane(plane_projector)
        self.orthogonal_directions = [
            Direction.from_xyz((0.2, 0.2, -0.25)),
            Direction.from_xyz((-7.0, 2.0, 2.0))
        ]
        self.orthogonal_rays = [Ray(self.position, direction)
                                for direction in self.orthogonal_directions]

    def tearDown(self):
        self.clean_state()

    def test_plane_contains_position(self):
        point = self.position
        distance_from_plane = self.plane.distance_to_point(point)
        self.assertAlmostEqual(0.0, distance_from_plane)

    def test_plane_contains_orthogonal_rays(self):
        self.then_plane_contains_orthogonal_rays()

    def then_plane_contains_orthogonal_rays(self):
        for orthogonal_ray in self.orthogonal_rays:
            for scale in [-2.0, -1.0, 0.0, 0.4, 1.0]:
                point = orthogonal_ray.scaled_endpoint(scale)
                distance_from_plane = self.plane.distance_to_point(point)
                self.assertAlmostEqual(0.0, distance_from_plane)
                # this really is testing Ray.distance_to_point
                length_of_orthogonal_ray = orthogonal_ray.direction.length()
                expected_distance_from_ray = fabs(scale) * length_of_orthogonal_ray
                actual_distance_from_ray = self.ray.distance_to_point(point)
                self.assertAlmostEqual(expected_distance_from_ray, actual_distance_from_ray)

    def test_plane_distance(self):
        self.then_plane_has_correct_distances()

    def then_plane_has_correct_distances(self):
        ray_length = vector_norm(self.unit_direction)
        self.assertEqual(1.0, ray_length)
        ray = self.unit_ray
        for scale in [-2.0, -1.0, 0.0, 0.4, 1.0]:
            point = ray.scaled_endpoint(scale)
            distance_from_plane = self.plane.distance_to_point(point)
            self.assertAlmostEqual(scale, distance_from_plane)

    def test_plane_construction_from_ray(self):
        self.when_plane_constructed_from_ray()
        self.then_plane_contains_orthogonal_rays()
        self.then_plane_has_correct_distances()

    def when_plane_constructed_from_ray(self):
        self.plane = Plane.orthogonal_to_ray(self.ray)

    def test_plane_intersects_ray(self):
        self.when_plane_constructed_from_ray()
        self.when_plane_intersects_other_ray()
        self.then_intersection_point_lies_on_plane()
        self.then_point_lies_on_othe_ray()

    def when_plane_intersects_other_ray(self):
        self.intersect_point = self.plane.intersect(self.other_ray)

    def then_intersection_point_lies_on_plane(self):
        self.assertAlmostEqual(0.0, self.plane.distance_to_point(self.intersect_point), 5)

    def then_point_lies_on_othe_ray(self):
        self.assertLess(0.0, self.other_ray.distance_to_point(self.intersect_point), 5)
Exemple #4
0
 def test_ray_has_cardinal_rays(self):
     for direction_name in ['up', 'down', 'left', 'right', 'forward', 'backward', 'unknown']:
         target = Ray.get_named_cardinal_ray(direction_name)
         expected_direction = Direction.get_named_cardinal_direction(direction_name)
         self.assertEqual(expected_direction.xyz, target.direction.xyz)
         self.assertEqual(Position.origin.xyz, target.position.xyz)
Exemple #5
0
 def when_ray_created_from_origin_endpoint(self):
     self.ray = Ray.from_origin_endpoint(self.expected_position, Position.from_xyz(self.endpoint_xyz))
Exemple #6
0
 def when_ray_created(self):
     self.ray = Ray(self.expected_position, self.expected_direction)
Exemple #7
0
class TestRay(unittest.TestCase):
    """
    Test Ray Class
    """

    def clean_state(self):
        self.expected_position = None
        self.expected_direction = None
        self.endpoint_xyz = None
        self.ten_scale_endpoint_xyz = None
        self.ray = None

    def setUp(self):
        self.clean_state()
        self.expected_position = Position.from_xyz((10.0, 20.0, 30.0))
        self.expected_direction = Direction.from_xyz((0.5, 0.4, 0.3))
        self.endpoint_xyz = (10.5, 20.4, 30.3)
        self.ten_scale_endpoint_xyz = (15.0, 24.0, 33.0)

    def tearDown(self):
        self.clean_state()

    def test_ray_normal_construction(self):
        self.when_ray_created()
        self.then_ray_has_normal_values()

    def when_ray_created(self):
        self.ray = Ray(self.expected_position, self.expected_direction)

    def then_ray_has_normal_values(self):
        self.then_ray_has_expected_position()
        self.then_ray_has_expected_direction()

    def then_ray_has_expected_position(self):
        self.assertAlmostEqual(self.expected_position.w, self.ray.position.w)
        self.assertAlmostEqual(self.expected_position.x, self.ray.position.x)
        self.assertAlmostEqual(self.expected_position.y, self.ray.position.y)
        self.assertAlmostEqual(self.expected_position.z, self.ray.position.z)

    def then_ray_has_expected_direction(self):
        self.assertAlmostEqual(self.expected_direction.w, self.ray.direction.w)
        self.assertAlmostEqual(self.expected_direction.x, self.ray.direction.x)
        self.assertAlmostEqual(self.expected_direction.y, self.ray.direction.y)
        self.assertAlmostEqual(self.expected_direction.z, self.ray.direction.z)

    def test_ray_construction_requires_valid_position(self):
        with self.assertRaises(TypeError):
            Ray("wrong stuff", self.expected_direction)

    def test_ray_construction_requires_valid_direction(self):
        with self.assertRaises(TypeError):
            Ray(self.expected_position, "wrong stuff")

    def test_ray_construction_refuses_swapped_arguments(self):
        with self.assertRaises(TypeError):
            Ray(self.expected_direction, self.expected_position)

    def test_ray_from_origin_endpoint(self):
        self.when_ray_created_from_origin_endpoint()
        self.then_ray_has_normal_values()

    def when_ray_created_from_origin_endpoint(self):
        self.ray = Ray.from_origin_endpoint(self.expected_position, Position.from_xyz(self.endpoint_xyz))

    def test_ray_wont_mutate(self):
        self.when_ray_created()
        with self.assertRaises(AttributeError):
            self.ray.position = Position((1.0, 2.0, 3.0, 4.0))
        with self.assertRaises(AttributeError):
            self.ray.direction = Direction((0.0, 2.0, 3.0, 4.0))

    def test_ray_has_cardinal_rays(self):
        for direction_name in ['up', 'down', 'left', 'right', 'forward', 'backward', 'unknown']:
            target = Ray.get_named_cardinal_ray(direction_name)
            expected_direction = Direction.get_named_cardinal_direction(direction_name)
            self.assertEqual(expected_direction.xyz, target.direction.xyz)
            self.assertEqual(Position.origin.xyz, target.position.xyz)

    def test_ray_endpoint(self):
        self.when_ray_created()
        endpoint = self.ray.endpoint;
        self.assertTrue(endpoint.is_position)
        self.assertEqual(self.endpoint_xyz, endpoint.xyz)

    def test_ray_scaled_endpoint(self):
        self.when_ray_created()
        endpoint = self.ray.scaled_endpoint(10.0);
        self.assertTrue(endpoint.is_position)
        self.assertEqual(self.ten_scale_endpoint_xyz, endpoint.xyz)
        self.assertLess(self.ray.distance_to_point(endpoint), 0.000001)

    def test_distance_to_ray(self):
        for ray in [Ray.up, Ray.down]:
            scaled_ray = ray.scaled_direction(10.0)
            for orthogonal_ray in [Ray.right, Ray.left, Ray.forward, Ray.backward]:
                scale_factor = 4.0
                scaled_orthogonal_ray = orthogonal_ray.scaled_direction(scale_factor)
                endpoint = scaled_orthogonal_ray.endpoint
                expected_distance = scale_factor
                actual_distance = ray.distance_to_point(endpoint)
                self.assertAlmostEqual(expected_distance, actual_distance)

    def test_ray_additon(self):
        self.when_ray_created()
        self.when_direction_added_to_ray()
        self.then_ray_has_translated_values()

    def when_direction_added_to_ray(self):
        self.ray = self.ray.add(Direction.from_xyz((100, 200, 300)))

    def then_ray_has_translated_values(self):
        self.then_ray_has_translated_position()
        self.then_ray_has_expected_direction()

    def then_ray_has_translated_position(self):
        self.assertTupleEqual((110, 220, 330), self.ray.position.xyz)