def __init__(self): # The energy bundle we'll use for now: nrm = 1/(N.sqrt(2)) direct = N.c_[[0,-nrm, nrm],[0,0,-1]] position = N.tile(N.c_[[0, self.source_y, self.source_z]], (1, 2)) self.bund = RayBundle(vertices=position, directions=direct, energy=N.r_[1, 1]) # The assembly for ray tracing: rot1 = N.dot(G.rotx(N.pi/4)[:3,:3], G.roty(N.pi)[:3,:3]) surf1 = rect_one_sided_mirror(width=10, height=10) surf1.set_rotation(rot1) surf2 = rect_one_sided_mirror(width=10, height=10) self.assembly = Assembly(objects=[surf1, surf2]) TracerScene.__init__(self, self.assembly, self.bund)
def test_tetrahedron(self): """Triangular mesh with oblique triangles""" # Face set: theta = np.arange(np.pi/2., np.pi*2, 2*np.pi/3) base_verts = np.vstack(( np.cos(theta), np.sin(theta), np.ones(3) )).T verts = np.vstack((np.zeros(3), base_verts)) faces = np.array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]) fset = TriangulatedSurface(verts, faces, perfect_mirror) # Flat floor: floor = rect_one_sided_mirror(5., 5., 1.) floor.set_location(np.r_[0., 0., 1.]) assembly = Assembly(objects=[fset, floor]) # Ray bundle of 3 rays starting at equal angles around the tetrahedron: theta -= np.pi/3. pos = np.vstack((np.cos(theta), np.sin(theta), np.ones(3)*0.2)) * 0.2 direct = np.vstack(( np.zeros((2,3)), np.ones(3) )) rayb = RayBundle(pos, direct, energy=np.ones(6)) # Check that the points on the floor describe an isosceles. engine = TracerEngine(assembly) engine.ray_tracer(rayb, 2, .05)[0] verts = engine.tree[-1].get_vertices() sizes = np.sqrt( np.sum((verts - np.roll(verts, 1, axis=1))**2, axis=0)) self.assertAlmostEqual(sizes[0], sizes[1]) self.assertAlmostEqual(sizes[2], sizes[1]) '''
def test_tetrahedron(self): """Triangular mesh with oblique triangles""" # Face set: theta = np.arange(np.pi / 2., np.pi * 2, 2 * np.pi / 3) base_verts = np.vstack((np.cos(theta), np.sin(theta), np.ones(3))).T verts = np.vstack((np.zeros(3), base_verts)) faces = np.array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]) fset = TriangulatedSurface(verts, faces, perfect_mirror) # Flat floor: floor = rect_one_sided_mirror(5., 5., 1.) floor.set_location(np.r_[0., 0., 1.]) assembly = Assembly(objects=[fset, floor]) # Ray bundle of 3 rays starting at equal angles around the tetrahedron: theta -= np.pi / 3. pos = np.vstack((np.cos(theta), np.sin(theta), np.ones(3) * 0.2)) * 0.2 direct = np.vstack((np.zeros((2, 3)), np.ones(3))) rayb = RayBundle(pos, direct, energy=np.ones(6)) # Check that the points on the floor describe an isosceles. engine = TracerEngine(assembly) engine.ray_tracer(rayb, 2, .05)[0] verts = engine.tree[-1].get_vertices() sizes = np.sqrt(np.sum((verts - np.roll(verts, 1, axis=1))**2, axis=0)) self.assertAlmostEqual(sizes[0], sizes[1]) self.assertAlmostEqual(sizes[2], sizes[1])
def setUp(self): """ Prepare an assembly with two subassemblies: one assembly representing a spherical lens behind a flat screen, and one asssembly representing a perfect mirror. The mirror will be placed at the two subassemblies' focus, so a paraxial ray will come back on the other side of the optical axis. Reference: In [1], the lensmaker equation """ # focal length = 1, thickness = 1/6 R = 1./6. back_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -R/2.]) front_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., R/2.], rotation=rotx(N.pi/2.)[:3,:3]) front_lens = AssembledObject(surfs=[back_surf, front_surf]) back_surf = Surface(FlatGeometryManager(), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -0.01]) front_surf = Surface(FlatGeometryManager(), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., 0.01]) glass_screen = AssembledObject(surfs=[back_surf, front_surf], transform=translate(0., 0., 0.5)) lens_assembly = Assembly(objects=[glass_screen, front_lens]) lens_assembly.set_transform(translate(0., 0., 1.)) full_assembly = Assembly(objects=[rect_one_sided_mirror(1., 1., 0.)], subassemblies = [lens_assembly]) self.engine = TracerEngine(full_assembly)
def __init__(self): # The energy bundle we'll use for now: nrm = 1 / (N.sqrt(2)) direct = N.c_[[0, -nrm, nrm], [0, 0, -1]] position = N.tile(N.c_[[0, self.source_y, self.source_z]], (1, 2)) self.bund = RayBundle(vertices=position, directions=direct, energy=N.r_[1, 1]) # The assembly for ray tracing: rot1 = N.dot(G.rotx(N.pi / 4)[:3, :3], G.roty(N.pi)[:3, :3]) surf1 = rect_one_sided_mirror(width=10, height=10) surf1.set_rotation(rot1) surf2 = rect_one_sided_mirror(width=10, height=10) self.assembly = Assembly(objects=[surf1, surf2]) TracerScene.__init__(self, self.assembly, self.bund)
def test_paraxial_ray(self): """A paraxial ray reaches the focus""" rb = RayBundle(N.c_[[0., 0.001, 1.]], N.c_[[0., 0., -1.]], energy=N.r_[1.], ref_index=N.r_[1.]) screen = rect_one_sided_mirror(5, 5) f = self.lens.focal_length() screen.set_transform(translate(0, 0, -f)) e = TracerEngine(Assembly([self.lens, screen])) vert, _ = e.ray_tracer(rb, 3, 1e-6) self.failUnlessAlmostEqual(vert[1,2], 0, 4)
def test_paraxial_ray(self): """A paraxial ray reaches the focus of a planoconvex lens""" rb = RayBundle(N.c_[[0., 0.001, 1.]], N.c_[[0., 0., -1.]], energy=N.r_[1.], ref_index=N.r_[1.]) screen = rect_one_sided_mirror(5, 5) f = self.lens.focal_length() screen.set_transform(translate(0, 0, -f)) e = TracerEngine(Assembly([self.lens, screen])) vert, _ = e.ray_tracer(rb, 3, 1e-6) self.failUnlessAlmostEqual(vert[1,2], 0, 4)
def test_image_size(self): """Image size of an object imaged by a biconcave lens matches theory""" origin = N.c_[[0., 0.001, 1.]] direct = -origin/N.linalg.norm(origin) rb = RayBundle(origin, direct, energy=N.r_[1.], ref_index=N.r_[1.]) # Magnification, see [1] p. 26. f = self.lens.focal_length() m = f/(origin[2] + f) # Image location, [ibid]: loc = origin[2]*m screen = rect_one_sided_mirror(5, 5) screen.set_transform(translate(0, 0, -loc)) e = TracerEngine(Assembly([self.lens, screen])) vert, _ = e.ray_tracer(rb, 3, 1e-6) self.failUnlessAlmostEqual(vert[1,2], -m*origin[1], 4)
def test_image_size(self): """Image size of an object imaged by a biconcave lens matches theory""" origin = N.c_[[0., 0.001, 1.]] direct = -origin / N.linalg.norm(origin) rb = RayBundle(origin, direct, energy=N.r_[1.], ref_index=N.r_[1.]) # Magnification, see [1] p. 26. f = self.lens.focal_length() m = f / (origin[2] + f) # Image location, [ibid]: loc = origin[2] * m screen = rect_one_sided_mirror(5, 5) screen.set_transform(translate(0, 0, -loc)) e = TracerEngine(Assembly([self.lens, screen])) vert, _ = e.ray_tracer(rb, 3, 1e-6) self.failUnlessAlmostEqual(vert[1, 2], -m * origin[1], 4)
def setUp(self): """ Prepare an assembly with two subassemblies: one assembly representing a spherical lens behind a flat screen, and one asssembly representing a perfect mirror. The mirror will be placed at the two subassemblies' focus, so a paraxial ray will come back on the other side of the optical axis. Reference: In [1], the lensmaker equation """ # focal length = 1, thickness = 1/6 R = 1. / 6. back_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -R / 2.]) front_surf = Surface(HemisphereGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., R / 2.], rotation=rotx(N.pi / 2.)[:3, :3]) front_lens = AssembledObject(surfs=[back_surf, front_surf]) back_surf = Surface(RoundPlateGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., -0.01]) front_surf = Surface(RoundPlateGM(R), opt.RefractiveHomogenous(1., 1.5), location=N.r_[0., 0., 0.01]) glass_screen = AssembledObject(surfs=[back_surf, front_surf], transform=translate(0., 0., 0.5)) lens_assembly = Assembly(objects=[glass_screen, front_lens]) lens_assembly.set_transform(translate(0., 0., 1.)) full_assembly = Assembly(objects=[rect_one_sided_mirror(1., 1., 0.)], subassemblies=[lens_assembly]) self.engine = TracerEngine(full_assembly)