wgs is an acronym for waveguide search. It is a program designed to aid in finding and optimizing optical elements. The program is divided into several components, discussed below.

The best way to think about my goal for wgs is this: Imagine a system as shown below:

On the left is a light source with some distribution of rays. On the right is some desired output distribution of rays. Between the two exists some optical element. The question is, how can we determine the geometry of the optical element given a source and desired output?

An obvious first approach is to use our intuition and design optical element with some parameters (e.g. a thin lens with a radius of curvature). wgs can search over these parameters and determine an optimal geometry.

A more interesting approach, and this is eventually my goal with wgs is to have the program come up with the geometry on its own.


The program spends most of its time ray-tracing. It fully implements the fresnel relations so as to accomodate polarization dependent effects. All of the geometries and rays are specified by vectors. There are no arcs, splines, etc. Only vectors-vector intersections are considered. This of course has a performance penalty, but greatly simplifies the code and allows for easy generation of arbitrary geometries.


wgs has a built-in visualizer that allows you to see what’s going on and interface with the program in real-time.

waveguide visualizer

waveguide visualizer

Above is a shot of some ray-tracing in action. This optic was designed to couple light from an LED (bottom) into an optical fiber (top). Red indicates reflection and blue indicates refraction. The amount of rays traced has been greatly reduced for clarity.

Thread Dispatcher

Ray-tracing is inherently parallelizable. wgs can use either pthreads or MPI to speed up computation.

Genetic Algoritm

wgs is capable of maximizing efficency through different genetic algorithms, implemented using GAUL - a genetic algorithm library written by Steward Adcock. Each of the parameters of a given optic is represented as a chromosome, and is mutated according to different selection rules.

This is the interesting part, and is also not fully implemented. As I mentioned before, what if the program was able to come up with the geometry of the optic on its own? The way wgs intends to do this is by generating random polygons, and using a genetic algorithm to “breed” their verticies together, splicing in new ones and interpolating between where needed. Polygons are generated and optimized by using a polygon generation tool rpg. As I have modified this software slightly for this project, I can provide the source for this.

poly1 poly2
poly3 poly4

An example of random polygons being traced.


machined waveguide

machined waveguide

Polycarbonate waveguide machined with parameters obtained from wgs

Obtaining wgs

wgs is under active development, and changes so often that it would not make sense to post the sources here. The program is avaliable under the GNU GPLv3. If you are interested in obtaining a copy, please email me at