# Ray tracer for transmission through simple geometries (MATLAB code)
Geometric ray tracing is a method in which rays of light are used to model the
scattering and transmission of light through optical systems. Light can be
modeled by geometric optics when the lenses, prisms or other objects are much
larger than the wavelength of the light, and does not concern effects such as
diffraction, interference.
In its simplest design the method a large amount of rays are generated from a
"light source" and their light paths are traced throughout the system. At each
lens, mirror or object surface encountered the refracted and reflected paths
are computed and followed. For the intensity of the transmission, reflection,
and absorption of the light rays, tables of refractive/absorption indices are
used.
For the full simulation we would simulate many rays and add up there
contributions. Thereby we can calculate the total intensity at each point in the
simulation "box" or only calculate the intensity for certain points (say a
surface upon which we project).
Here we focus on a simple 2D approach where objects are defined by polygons, and
their complex refractive indices. The source code can be found via the links
provided at the end.
## A simple 2D ray tracing procedure
The procedure to generate the path of a light ray can be computed as follows:
1. ray starts off with intensity I = 1 and a certain direction, given by
for example the directional cosines.
2. The line of the ray is followed until it hits a boundary of an object,
e.g. a surface of a prism. Whether the line arrived from inside or outside
the object is determined.
3. Material properties of the object (e.g. prism) are looked up:
refractive/absorption
index, and the expected transmission for typical polarizations (TE and TM).
Transmission and reflection coefficients are looked up as well.
4. Reflected ray path and refracted ray paths are calculated using Snell's
law. Their intensities are calculated according to their transmission T and
reflection R coefficients.
5. The new paths are followed and start again from step 1, although with a
different intensity (calculated in step 4).
In two dimensions, we can convert this in pseudo-code in Matlab as follows:
```matlab
%% Procedure for 2D ray tracing.
% Parameters
wl = 550; % Wavelength in nm (only used for the refractive index)
dx = 0.01; % Distance in arbitrary units (au)
envFile = "env.mat"; % File containing the object definitions
% Load the objects in the environment
[objects, rect] = loadEnvironment(envFile);
% Define the initial rays. Rays is a [I, x0, y0, cosx, cosy, n, k, iter, id, parentID]
rays = generateRaysFromPoint(x0, y0, nRays);
% pre-define the list of "rays" for each iteration
raysList = cell(nIter, 1);
% Iterate over the collisions, with number of iterations = nIter
for i = 1:nIter
[raysT, raysR] = propagateRays(rays, objects);
raysList{i} = [raysT; raysR];
end
% Merge all iterations
raysAll = mergeList(raysList);
% Density of all rays
im = getRayDensity(raysAll, rect, dx);
% plot the ray density
imagesc(im);
```
Where the functions are defined below. We start with defining the function
The idea in this trivial example is that the shapes can be easily defined and
connected, a useful feature for simulations. The particle properties for this
example are then saved in a csv-file and can be used downstream for near-field
simulations. The first rows of the output format are targeted to
[CELES](https://disordered-photonics.github.io/celes/), a MATLAB toolbox to compute
the electromagnetic scattering for clusters of spheres.
## Files
- Main MATLAB script to run the example: raytracer2d.m
- Environment class helps loading/saving/constructing the (polygon) objects: Environment.m
- Shapes is Enum listing the shapes: Shape.m
- Output csv-file of the example: example_cluster_properties.csv