Moving optical elements
Optical elements that implement the BeamletOptics.AbstractObject interface, as well as the BeamletOptics.AbstractShapes they are built from, can be moved with the commands listed in the Kinematics section. When objects are manipulated, they are translated and rotated around the origin of their local coordinate system, i.e. their position, which the constructor of the element defines (e.g. the front vertex of a lens). Their orientation defines their local fixed coordinate system.
Detectors
Moving a detector empties its recorded hits.
using BeamletOptics
mirror = RoundPlanoMirror(25.4e-3, 5e-3)
translate3d!(mirror, [0, 0.1, 0]) # move 10 cm along the global y-axis
zrotate3d!(mirror, deg2rad(45)) # rotate 45° about z through the mirror positionObjects with multiple shapes
Objects which consist of more than one shape, e.g. a CubeBeamsplitter or a doublet lens, move all of their shapes as one rigid body. Unless the object defines its own reference point, the position and orientation of its first shape are used as the kinematic center, see BeamletOptics.MultiShape.
Groups of optical elements
For the easier representation of a group of BeamletOptics.AbstractObjects that moves as one, the ObjectGroup can be used. Refer to the Lens groups example for more information. A new group is created by ObjectGroup(objects, T = Float64), with its center at the global origin and the identity orientation, independent of where its members are. rotate3d! therefore rotates a new group about the global origin. The group's pivot (its center) can be moved without moving its members via set_pivot3d!.
Objects and subgroups are added to and removed from a group like from a System, where they are, without changing the pose of the group:
group = ObjectGroup([lens1, lens2])
push!(group, lens3) # lens3 now moves with the group
delete!(group, lens1) # lens1 stays where it is and no longer moves with the group
pop!(group) # removes and returns lens3, popat!(group, i) the i-th partAdded objects join the current frame of the group: reset_rotation3d! and reset_translation3d! of the group undo its rotation and translation so far and move the added objects by the same amount, like parts put onto a mount that was turned before.
A StaticSystem keeps the objects that its groups had when it was built: trace a changed group in a System, or build a new StaticSystem.
BeamletOptics.ObjectGroup Type
ObjectGroup(objects, T = Float64)A tree-like storage container for groups of objects. Can store individual objects and subgroups. Main purpose is handling of, i.e., groups of lenses.
objects is a vector or tuple of AbstractObjects and subgroups. A new group has its center at the global origin and the identity orientation, independent of the poses of its objects, so rotate3d! rotates about the global origin until set_pivot3d! moves the pivot.
Fields
center: a point in 3D space which is regarded as the reference origin of the groupdir: a 3x3 matrix that describes the commonorientationof the groupobjects: storesAbstractObject, can also store subgroups of typeAbstractObjectGroup
Each of its objects is traced and interacts on its own, read them via objects(group).
Kinematic
An ObjectGroup implements the kinematic API, see BeamletOptics.AbstractKinematicTrait. The following logic is applied to
translate3d!: all objects in the group are translated by the offset vectortranslate_to3d!: all objects are moved in parallel such that the groupcenteris equal to the target positionrotate3d!: all objects are rotated around thecenterpoint with respect to their relative positionset_pivot3d!: moves the groupcenter(the pivot used above) without moving any of itsobjects
The objects must be either all static or all movable, otherwise the constructor throws an ArgumentError. The group takes that kinematic class, see BeamletOptics.AbstractKinematicTrait.
Changing the objects
Objects and subgroups are added to and removed from the top level of the group via push!, delete!, pop! and popat!, like those of a System. The constructor copies the vector or tuple it is given, such that these do not change it.
BeamletOptics.set_pivot3d! Method
set_pivot3d!(group::AbstractObjectGroup, pivot)Moves the kinematic pivot (center) of group to pivot, without moving any of its objects. The pivot is the reference point used by rotate3d!, translate_to3d! and reset_translation3d!; the group orientation is unchanged.
Example
Rotate a lens group about its first surface instead of the group's default center:
group = ObjectGroup([lens1, lens2])
set_pivot3d!(group, position(lens1))
rotate3d!(group, [0, 0, 1], deg2rad(5)) # rotates about lens1's position, not the old centerBase.push! Method
push!(group::ObjectGroup, objects::ObjectOrGroup...) -> groupAdds the objects (or object groups) at the top level of the group. The pose of the group (its pivot and orientation) and the poses of the objects stay as they are, i.e. the objects are added where they are.
The objects join the current frame of the group, like parts put onto a mount that was moved before: reset_rotation3d! and reset_translation3d! of the group undo its rotation and translation so far and move the added objects by the same amount, although these did not take part in that motion.
Throws an ArgumentError and adds nothing if an object is already part of the group, directly or within a subgroup, or if the objects and those of the group would not be all static or all movable, see BeamletOptics.AbstractKinematicTrait. Objects are compared by identity.
The group does not know the systems that hold it: an object that is also part of such a system is then traced twice, so remove it from the system first, e.g. via delete!(system, object). Beams that were solved before must be solved again, see push!(system, objects...). A StaticSystem keeps the objects that its groups had when it was built and does not trace the new objects: trace the group in a System, or build a new StaticSystem. The group must not be changed while a system that holds it is being solved.
Base.delete! Method
delete!(group::ObjectGroup, object::ObjectOrGroup) -> groupRemoves the top-level object (or subgroup) from the group, compared by identity. The pose of the group and the pose of the object stay as they are. Nothing happens for an object that is not part of the group. An object within a subgroup throws an ArgumentError: remove it from its subgroup instead. A group without objects remains a valid, empty group.
Beams that were solved before must be solved again, see delete!(system, object). A StaticSystem keeps the objects that its groups had when it was built and still traces the removed object: trace the group in a System, or build a new StaticSystem. The group must not be changed while a system that holds it is being solved.
Base.pop! Method
pop!(group::ObjectGroup) -> ObjectOrGroupRemoves the last top-level object (or subgroup) of the group and returns it. The pose of the group and the pose of the object stay as they are, see delete!(group, object). An empty group throws an ArgumentError.
Base.popat! Method
popat!(group::ObjectGroup, i::Integer) -> ObjectOrGroupRemoves the i-th top-level object (or subgroup) of the group and returns it. The index counts the objects and subgroups as they were added, a subgroup counts as one. An index out of bounds throws a BoundsError. The pose of the group and the pose of the object stay as they are, see delete!(group, object).
Assemblies: group or multi-shape object
An assembly such as a telescope, a periscope or an interferometer arm can be modeled in two ways, and the choice follows from whether its parts touch:
| Parts of the assembly | Model | interact3d |
|---|---|---|
| separate, with air between them | an ObjectGroup or an own subtype of BeamletOptics.AbstractObjectGroup | none: each part is traced and interacts on its own |
| touching and interacting as one, e.g. cemented or with a shared face | an BeamletOptics.AbstractObject with the BeamletOptics.MultiShape trait, like the CubeBeamsplitter | required: the solver hands every hit to the object, which forwards it to the part that was hit |
The solver can find out by itself which of several separate parts a ray hits next. Parts that touch need a BeamletOptics.Hint across their shared face, which only the component knows. An own subtype of AbstractObjectGroup adds named parts and an own constructor to a group and needs no interact3d method; its fields are listed in the docstring of BeamletOptics.AbstractObjectGroup, its constructor calls BeamletOptics.check_kinematic_members on its objects, and the agent skill has a complete example in templates/08_custom_group.jl. A MultiShape object without an interact3d method stops every ray that hits it, with the warning No interact3d method defined for the MultiShape object.
BeamletOptics.check_kinematic_members Function
check_kinematic_members(members)Throws an ArgumentError if some members of a container are Static and some are Movable. Empty collections pass. The constructor of an own AbstractObjectGroup calls it on its objects.