Skip to content

Kinematic system ​

This page explains how the kinematic API described in the Kinematics section is implemented, and what a developer has to provide so that a new optical element, ray or beam type can be moved with it.

Kinematic traits ​

Analogous to the BeamletOptics.AbstractShapeTrait of the Geometry representation, the kinematic API is built on a trait that is dispatched on via multiple dispatch. Every public kinematic function, e.g. translate3d!(x, offset), forwards to a trait-specific method translate3d!(kinematic_trait_of(x), x, offset). As on the Geometry representation page, solid arrows are labeled with the field that leads from one type to the next, dotted arrows point to subtypes.

BeamletOptics.AbstractKinematicTrait Type

The kinematic trait defines whether an entity can be moved by the kinematic API (translate3d!, rotate3d!, ...). It is returned by kinematic_trait_of and follows the same dispatch pattern as AbstractShapeTrait: every public function e.g. translate3d!(x, args...) forwards to translate3d!(kinematic_trait_of(x), x, args...).

Two traits are defined:

  1. Static: x cannot be moved, every kin. function throws an ArgumentError

  2. Movable: x can be moved; its frame (Oriented or Directed) selects orientation- or direction-based behaviour

A subtype of a movable abstract type can opt out of the kinematic API by declaring its own kinematic_trait_of method, e.g.

julia
struct FixedMirror{T, S <: AbstractShape{T}} <: AbstractObject{T}
    shape::S
end

kinematic_trait_of(::FixedMirror) = Static()

Every kinematic function on a FixedMirror now throws an ArgumentError; its getters (position, orientation, ...) stay available.

Containers

All members of a container (ObjectGroup, UnionSDF/DifferenceSDF, AbstractBeamGroup) must be either all Static or all Movable. Frames can still be mixed. This must be checked in the respective constructors; nesting is then covered because a nested container already has a uniform class from its own constructor. The container then takes that class: Static if all members are Static, else Movable(Oriented()). All shapes returned by shape(object) of a MultiShape object must be movable, since MultiShape objects (e.g. a CubeBeamsplitter) have no shared constructor to enforce this.

source
BeamletOptics.kinematic_trait_of Function

Returns the AbstractKinematicTrait of x. Defaults to Static(). Movable types declare Movable(Oriented()) or Movable(Directed()).

source

A composite takes the kinematic class of its operands, which the constructor ensures to be either all static or all movable, see BeamletOptics.AbstractKinematicTrait.

source

Static and movable entities ​

Whether an entity can be moved at all is defined by its trait. The fallback of BeamletOptics.kinematic_trait_of is BeamletOptics.Static, so types that do not opt in cannot be moved. The abstract types BeamletOptics.AbstractObject, BeamletOptics.AbstractRay, BeamletOptics.AbstractBeam and BeamletOptics.AbstractBeamGroup declare themselves BeamletOptics.Movable, so a new subtype of them only has to implement the kinematic primitives listed below.

BeamletOptics.Static Type

Represents a value that cannot be moved. Every kinematic function throws an ArgumentError; the getters (e.g. position, orientation) stay available. This is the fallback of kinematic_trait_of.

source
BeamletOptics.Movable Type

Represents a value that can be moved by the kinematic API. The frame field (Oriented or Directed) selects orientation- or direction-based behaviour of the derived functions.

Rotations are applied about the own position of the value unless a pivot is passed explicitly. A rotation axis can have any non-zero length (it is normalized internally).

Kinematic functions

  • translate3d!: moves x by an offset vector (primitive, implemented per type)

  • rotate3d!: rotates x by a rotation matrix R about position(x), or about a given pivot if one is passed (the R-only form is the primitive, implemented per type; the axis/angle and pivot forms are derived from it)

  • translate_to3d!: moves x so that position(x) coincides with a target point

  • xrotate3d! / yrotate3d! / zrotate3d!: rotate x by an angle θ [rad] about the global x-, y- or z-axis through position(x)

  • align3d!: rotates x about position(x) so that direction(x) is aligned with a target vector

  • reset_translation3d!: moves x so that position(x) is the global origin; available for every Movable, including rays, beams and beam groups

  • reset_rotation3d!: only available for Oriented values, where it rotates x back to identity orientation; for Directed values (rays, beams) it throws an ArgumentError, use align3d! instead

  • direction: for Oriented values this is the local y-axis, orientation(x)[:, 2]; Directed values provide their own getter

Sources (rays, beams and beam groups) are additionally reset to their untraced start state by every one of the functions above: a moved but already-traced source would otherwise keep rays or child beams belonging to the old, now geometrically wrong, light path. Moving a beam that is not the root of its beam tree (e.g. one created by a beamsplitter interaction) throws an ArgumentError; move its root beam instead.

Implementation reqs.

If kinematic_trait_of(::Foo) = Movable(...) is declared, Foo must implement the following:

  • position

  • translate3d!(::Movable, x::Foo, offset): moves x by offset

  • rotate3d!(::Movable, x::Foo, R::AbstractMatrix): rotates x by R about position(x)

All other kin. functions listed above are derived from these two primitives.

source

Oriented and directed frames ​

The frame of a BeamletOptics.Movable entity selects whether the derived functions work on a full local coordinate system or only on a direction vector. Shapes, objects and beam groups are BeamletOptics.Oriented, whereas rays and beams are BeamletOptics.Directed.

BeamletOptics.AbstractKinematicFrame Type

Reference frame of a Movable value, either Oriented or Directed.

source
BeamletOptics.Oriented Type

Reference frame of a movable value with a full local coordinate system, e.g. shapes, objects and beam groups.

Implementation reqs.

  • position / position!

  • orientation / orientation!: a right-handed orthonormal 3x3 matrix

direction returns the local y-axis, i.e. orientation(x)[:, 2]. reset_rotation3d! rotates x by transpose(orientation(x)) about its position and then sets the orientation to the identity.

source
BeamletOptics.Directed Type

Reference frame of a movable value that only has a direction but no orientation, e.g. rays and beams.

Implementation reqs.

  • position

  • direction: the direction getter of the type

reset_rotation3d! throws an ArgumentError, use align3d! instead.

source

Type-specific implementation requirements ​

The primitives translate3d!(::Movable, x, offset) and rotate3d!(::Movable, x, R) are implemented differently for the individual abstract types. The requirements for subtypes are listed in the Kinematic section of the respective docstrings: