def test_refract(self): screen = geometry.Screen() ray = rays.Ray(origin=_utils.pos(.5, .5, 1), k=_utils.vec(0, 0, -1)) screen.refract(ray, _utils.pos(.5, .5, 0), 1) self.assertTrue(ray.terminated) self.assertSameArray(ray.pos, _utils.pos(.5, .5, 0))
def test_properties(self): screen = geometry.Screen() ray = rays.Ray(origin=_utils.pos(.5, .5, 1), k=_utils.vec(0, 0, -1)) screen.refract(ray, _utils.pos(.5, .5, 0), 1) self.assertEqual(type([]), type(screen.hits)) self.assertEqual(1, len(screen.hits)) self.assertEqual(ray, screen.hits[0])
def test_intersect_axis(self): ray = rays.Ray(k=_utils.vec(0, 0, 1)) origin = _utils.pos(1, 0, 1) axis = _utils.vec(0, 1, 0) pt_ray, pt_axi = ray.intersect_axis(origin, axis) self.assertApproxArray(pt_ray, _utils.pos(0, 0, 1)) self.assertApproxArray(pt_axi, _utils.pos(1, 0, 1)) self.assertAlmostEqual(_utils.vabs(pt_ray - pt_axi), 1)
def test_intersect(self): plane = geometry.Plane(pos=np.zeros(3), width=_utils.vec(1, 0, 0), height=_utils.vec(0, 1, 0)) ray = rays.Ray(_utils.pos(.5, .5, 7), k=_utils.vec(0, 0, -1)) self.assertApproxArray(plane.intersect(ray), _utils.pos(.5, .5, 0)) ray = rays.Ray(_utils.pos(.5, .5, 7), k=_utils.vec(0, 0, 1)) self.assertEqual(plane.intersect(ray), None)
def test_refract(self): # Check it updates position mirror = MockGeometryNormal(geometry.Mirror()) ray = rays.Ray(k=_utils.vec(0, 1, 1)) new_pos = _utils.pos(10, 34.2, -70) mirror.refract(ray, new_pos, 1) self.assertSameArray(new_pos, ray.pos) # Check angle in is angle out tests = [ (_utils.vec(5, 0, 0), _utils.vec(1, 0, 0), 1, 2), (_utils.vec(1, 3, 5), _utils.vec(1, -2, 7), 1, 3.1), (_utils.vec(0.246, 5.8, 24.9), _utils.vec(45.6, -2.888, 3.1), 1, 1.1), (_utils.vec(-3, 1.8, 0), _utils.vec(1.7, 2.2, -1), 1, 7.24), (_utils.vec(43.4, 9.38, -5), _utils.vec(-1.7, 22, -1), 2.1, 4.15), ] def angle(a, b): return np.arccos(abs(a.dot(b) / _utils.vabs(a) / _utils.vabs(b))) for k, normal, n_prev, n_lens in tests: mirror = MockGeometryNormal(geometry.Mirror(n=n_lens), normal) ray = rays.Ray(k=k) ang_1 = angle(ray.k, normal) mirror.refract(ray, np.zeros(3), n_prev) ang_2 = angle(ray.k, normal) self.assertAlmostEqual(ang_1, ang_2)
def test_refract(self): # Check it updates position lens = MockGeometryNormal(geometry.Lens()) ray = rays.Ray(k=_utils.vec(0, 1, 1)) new_pos = _utils.pos(10, 34.2, -70) lens.refract(ray, new_pos, 1) self.assertSameArray(new_pos, ray.pos) # Check Babinet’s principle holds tests = [ (_utils.vec(5, 0, 0), _utils.vec(1, 0, 0), 1, 2), (_utils.vec(1, 3, 5), _utils.vec(1, -2, 7), 1, 3.1), (_utils.vec(0.246, 5.8, 24.9), _utils.vec(45.6, -2.888, 3.1), 1, 1.1), (_utils.vec(-3, 1.8, 0), _utils.vec(1.7, 2.2, -1), 1, 7.24), (_utils.vec(43.4, 9.38, -5), _utils.vec(-1.7, 22, -1), 2.1, 4.15), (_utils.vec(1.4, 2.8, 3.9), _utils.vec(-1.7, 22, -1), 2, 2), ] def angle(a, b): return np.arccos(abs(a.dot(b) / _utils.vabs(a) / _utils.vabs(b))) for k, normal, n_prev, n_lens in tests: lens = MockGeometryNormal(geometry.Lens(n=n_lens), normal) ray = rays.Ray(k=k) n_1_sin_1 = n_prev * np.sin(angle(ray.k, normal)) lens.refract(ray, np.zeros(3), n_prev) n_2_sin_2 = n_lens * np.sin(angle(ray.k, normal)) self.assertAlmostEqual(n_1_sin_1, n_2_sin_2)
def test_pos(self): pos = _utils.pos(1, 2, 3) self.assertTrue(type(pos) == np.ndarray) self.assertTrue(len(pos) == 3) self.assertEqual(pos[0], 1) self.assertEqual(pos[1], 2) self.assertEqual(pos[2], 3)
def test_contains(self): plane = geometry.Plane(pos=np.zeros(3), width=_utils.vec(1, 0, 0), height=_utils.vec(0, 1, 0)) self.assertTrue(plane.contains(_utils.pos(0.5, 0.5, 0))) self.assertTrue(plane.contains(_utils.pos(1e-20, 1e-20, 0))) self.assertTrue(plane.contains(_utils.pos(0.5, 0.5, 0 + 1e-30))) self.assertFalse(plane.contains(_utils.pos(1.5, 0.5, 0))) self.assertFalse(plane.contains(_utils.pos(0, -0.5, 0))) self.assertFalse(plane.contains(_utils.pos(0.5, 0.5, 0.1)))
def test_refract_sphere_lens(self): lens = geometry.SphereLens(1, 1, 1, n=1.0, pos=_utils.pos(0, 0, 1)) ray = rays.Ray(origin=np.array([0, 0, 2])) ray.k = np.array([0, 0, -1]) inter = lens.intersect(ray) lens.refract(ray, inter, 1.0) self.assertApproxArray(ray.k, np.array([0, 0, -1])) self.assertSameArray(inter, ray.pos) self.assertEqual(None, lens.intersect(ray)) ray = rays.Ray(origin=np.array([0, 0, 1 + 1e-5])) ray.k = np.array([0, -1, -1]) inter = lens.intersect(ray) lens.refract(ray, inter, 1.0) self.assertApproxArray(ray.k, np.array([0, -1, -1] / np.sqrt(2)), eps=1e-4) self.assertSameArray(inter, ray.pos) self.assertEqual(None, lens.intersect(ray))
def test_contains(self): lens = geometry.Sphere(1, 0.5, 0.5, axis=np.array([1, 0, 0]), pos=_utils.pos(1, 0, 0)) are_in = [ np.array([0.5, 0, 0]), np.array([1.0, 0, 0]), np.array([0.5, 0.1, 0.1]), np.array([0.5, -0.1, 0.1]), ] are_out = [ np.array([0.4, 0, 0]), np.array([1.0, 0.01, 0]), np.array([-0.5, 0.1, 0.1]), np.array([0.2, 0.5, 0.5]), ] for pos in are_in: self.assertTrue(lens.contains(pos)) for pos in are_out: self.assertFalse(lens.contains(pos))
def test_intersect(self): lens = geometry.Sphere(1, 1, 1, pos=_utils.pos(0, 0, 1)) ray = rays.Ray(origin=np.array([0, 0, 2])) ray.k = np.array([0, 0, -1]) self.assertSameArray(lens.intersect(ray), np.array([0, 0, 1])) ray.k = np.array([0, 1, -2]) self.assertApproxArray(lens.intersect(ray), np.array([0, .6, .8])) ray.pos = np.array([0, 0, 0.1]) ray.k = np.array([0, 0, 1]) self.assertEqual(None, lens.intersect(ray)) ray.pos = np.array([0, 0, -1]) ray.k = np.array([0, 0, -1]) self.assertEqual(None, lens.intersect(ray)) ray = rays.Ray(origin=np.array([-1, 0, 2])) ray.k = np.array([1, 0, -1]) self.assertApproxArray(np.array([0, 0, 1]), lens.intersect(ray)) with self.assertRaises(AttributeError): lens.intersect(None)
def test_refract(self): # As refract in Splitter invokes # super, our proxy class will # cause runtime errors class MockSplitter(geometry.Splitter): def normal(*_): return _utils.vec(0, 0, 1) # Check it updates position splitter = MockSplitter() ray = rays.Ray(k=_utils.vec(0, 1, 1)) new_pos = _utils.pos(10, 34.2, -70) splitter.refract(ray, new_pos, 1) self.assertSameArray(new_pos, ray.pos) # Check angle in is angle out tests = [ (_utils.vec(5, 0, 0), 1, 2), (_utils.vec(1, 3, 5), 1, 3.1), (_utils.vec(0.246, 5.8, 24.9), 1, 1.1), (_utils.vec(-3, 1.8, 0), 1, 7.24), (_utils.vec(43.4, 9.38, -5), 2.1, 4.15), ] def angle(a, b): return np.arccos(abs(a.dot(b) / _utils.vabs(a) / _utils.vabs(b))) for k, n_prev, n_lens in tests: splitter = MockSplitter(n=n_lens) ray = rays.Ray(k=k) ang_1 = angle(ray.k, splitter.normal()) splitter.refract(ray, np.zeros(3), n_prev) ang_2 = angle(ray.k, splitter.normal()) self.assertAlmostEqual(ang_1, ang_2)
def test_normal(self): lens = geometry.Sphere(1, 1, 1, pos=_utils.pos(0, 0, 0)) normal = _utils.vec(0, 0, 1) self.assertSameArray(normal, lens.normal(_utils.pos(0, 0, 0)))