simulated rayleigh scattering - brigham young university ...€¦ · simulated rayleigh scattering...

110
Simulated Rayleigh Scattering by James Nelson A senior thesis submitted to the faculty of Brigham Young University - Idaho in partial fulfillment of the requirements for the degree of Bachelor of Science Department of Physics Brigham Young University - Idaho July, 2015

Upload: vuthu

Post on 30-May-2018

233 views

Category:

Documents


0 download

TRANSCRIPT

Simulated Rayleigh Scattering

byJames Nelson

A senior thesis submitted to the faculty of

Brigham Young University - Idaho

in partial fulfillment of the requirements for the degree of

Bachelor of Science

Department of Physics

Brigham Young University - Idaho

July, 2015

BRIGHT YOUNG UNIVERSITY - IDAHO

DEPARTMENT APPROVAL

of a senior thesis submitted by

James Nelson

This thesis has been reviewed by the research committee, senior thesis coordinator, anddepartment chair and has been found to be satisfactory.

Date Todd Lines, Advisor

Date Evan Hansen, Committee Member

Date Kevin Kelley, Committee Member

Date Stephen McNeil, Department Chair

ABSTRACT

Simulated Rayleigh Scattering

James Nelson

Department of Physics

Bachelor of Science

A simulator was created, which makes use of Monte Carlo to model the behavior of scattered

electromagnetic radiation in a given medium. The program provides a flexible framework which

can be adapted to explore various scattering phenomena from a semi-classic macroscopic point

of view. Proper adaptation of the simulator does require some background knowledge of object-

oriented programming. The geometry of the test and the output produced must be configured by

the user. A test to simulate Rayleigh scattering, the most dominant type of scattering for visible

light in our atmosphere, was implemented and compared against actual measurement of skylight

both qualitatively and quantitatively. It was found that the generated data had the characteristics

of natural skylight.

Acknowledgements

Thank you to Todd Lines for giving me the idea for this project, in the first place, and giving

helpful feedback and insight through out it’s development. And thank you Matthew Brownell for

configuring the Romney cpu cluster and providing technical support.

Contents

1 Introduction 11.1 Objective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Introduction to Rayleigh Scattering . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.4 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Methods 92.1 Monte Carlo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2 System Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.3 Simulator Conditions and Assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . 102.4 Modeling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.5 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3 Results 153.1 Comparison with Skylight . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.3 Future Research . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

A Simulator Source Code 31

vii

List of Figures

1.1 Abstract diagram of the components of the simulator. . . . . . . . . . . . . . . . . . 21.2 Class hierarchy of the simulator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 This figure indicates a full hemisphere view of the direction and magnitude of polar-

ization induced by Rayleigh scattering, as viewed from an observer looking up withthe sun directly above them. Adapted from from [6]. . . . . . . . . . . . . . . . . . . 4

1.4 The top part of the figure shows the intensity of scattering for the isotropic events.The middle section shows the distribution created by the anisotropic events. EveryRayleigh scattering event falls into one of these two categroies. The last part showsthe two of them added together. Taken from [5]. . . . . . . . . . . . . . . . . . . . . 6

3.1 This is a full sky image taken by Dr Shaw in Manua Loa, Hawaii. Note the band ofstrongly polarized light. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.2 This plot (provided by Dr. Shaw) shows Rayleigh scattering vs scattering angle (an-gle between original and scattered directions). Unpolarized light with a wavelengthof 650 nm, and particles with a 1 nm radius. . . . . . . . . . . . . . . . . . . . . . . 17

3.3 Angle from source vs angle of polarization (relative to the z-axis) . . . . . . . . . . . 173.4 Angle from source vs angle of incidence (relative to the z-axis) . . . . . . . . . . . . 183.5 Angle from source vs frequency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.6 Wavelength dependence of Rayleigh Scattering (adapted from Dr. Shaw) . . . . . . 203.7 Histogram of the number of detected scattered photons sorted by frequency. . . . . . 213.8 Frequency vs angle of polarization (from the Z-axis) . . . . . . . . . . . . . . . . . . 223.9 Frequency vs angle of incidence (from the Z-axis) . . . . . . . . . . . . . . . . . . . . 233.10 Angle from source vs relative polarization . . . . . . . . . . . . . . . . . . . . . . . . 243.11 Frequency vs Angle of Polarization (from the Z-axis) . . . . . . . . . . . . . . . . . . 253.12 Histogram showing the distribution of relative polarizations detected with an angle

of incidence of 45 degrees. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

ix

x

Chapter 1

Introduction

1.1 Objective

The goal was to write a simulator that can accurately model the behavior of electromagnetic

radiation traveling through a medium. By implementing known details at the microscopic level,

such as calculation of the cross section and the probability distribution of the scattered photons that

could be produced, the model should produce distributions of data that have the same macroscopic

qualities and dependencies as physically observed in that type of scattering.

1.2 Overview

The program uses very generic and adaptable classes that can be useful in a wide variety of tests.

Then, more specific sub-classes were implemented to represent specific, known physical characteris-

tics. The end result of these sub-classes is a simulator that makes use of Monte Carlo to give results

that are statistically reliable, if run a sufficient number of times. The program allows the user to

specify the conditions and configuration of the test, as well as which resulting data is relevant to

include in the output. The simulator was used to model visible light as it passes through the air,

for the idealistic case of Rayleigh scattering only, and the generated results were validated against

actual measurement.

Figure 1.1 illustrates the basic idea behind the simulator. Photons are emitted from a source,

and after being scattered in a medium may or may not be absorbed by the detector. Each simulation

1

Figure 1.1: Abstract diagram of the components of the simulator.

must include the locations and dimensions of the source, medium, and detector class configured.

Every detected photon will be included in the output of the program. Photons that are not detected

will not be output.

A basic overview of the class structure is provided in figure 1.2. The detector, medium, and

source class are the generic parent classes for more specific implementations. Together with the

photon class, these make up the main components of a simulator implementation.

1.3 Introduction to Rayleigh Scattering

Rayleigh scattering occurs when incident photons interact with spherical or very nearly spherical

particles whose radius is much smaller that the wavelength of the incident light. This condition is

met in the case of visible light and the main components of our atmosphere (N2, O2, Ar, and CO2).

It also happens that visible light and radio waves are the only two ranges in the electromagnetic

2

Figure 1.2: Class hierarchy of the simulator.

spectrum where absorbance is greatly reduced and nearly all interactions result in a scattered

photon of the same energy (inelastic scattering) rather than converting some or all of that energy

into thermal motion of the air particles.

Rayleigh scattering was originally discovered and investigated by John William Strutt, the third

Lord of Rayleigh, in 1871. He correctly determined that this scattering is inversely proportional to

the wavelength raised to the fourth power. The equation to calculate the intensity of an unpolarized

beam of Rayleigh scattered light is

I =I0r2α2(

λ)4

1 + cos2(θ)

2, (1.1)

where I0 is the original intensity, r is the distance traveled, α is a constant related to the po-

larizability of a particle, λ is the wavelength of the light, and θ is the azimuthal angle from the

original direction. In other words, the degree that Rayleigh scattering tends to affect light is highly

dependent on the wavelength of the light. This make the air somewhat like a big, fuzzy prism.

It also has a tendency to induce a partial polarization in completely unpolarized light. More

specifically, light scattered perpendicular to the beam will be strongly polarized in the azimuthal

direction compared to that beam as indicated in figure 1.4. That is how anti-glare lenses work.

3

Figure 1.3: This figure indicates a full hemisphere view of the direction and magnitude of polariza-tion induced by Rayleigh scattering, as viewed from an observer looking up with the sun directlyabove them. Adapted from from [6].

If the sun is directly above you, most of the light reflecting off the horizon from all directions in

vertically polarized. So a lens that filters vertically polarized light can remove most of the glare

without impeding visibility. Turn the lens 90 degrees and the glare comes back. Both [1] and [4]

give a more thorough treatment of polarization and the scattering of light.

In the context of visible light, Rayleigh scattering is the most dominant type of scattering in our

atmosphere. It is responsible for the blue hue that can be observed in the sky on a cloudless day.

This happens because photons with higher frequencies (green, blue, and purple) are exponentially

more likely to be scattered than lower frequency photons (such as red, orange, and yellow). If you

look in any direction other than directly at the sun, you are only seeing photons that have scattered

at least once and probably several times, and so the vast majority of them are these higher energy

photons that together appear blue. It is for this same reason that we observe red orange and yellow

shades at sunset or sunrise. At those angles, the atmosphere that the light must travel through

to reach an observer on the ground is much thicker. The higher frequency photons have scattered

so many times while traveling that they have become diffuse, and most of them scatter in some

4

direction other than that of the original beam. Lower frequency photons on the other hand, have

had a chance to scatter just the needed number times without being filtered out.

This phenomena is really the result of a pair of possible scattering events, both of which are

depicted in the figure . One type of event is completely isotropic. It does not affect the photon in

anyway, except to change its trajectory, and the transmitted photon has an even probability of going

in any direction. The other type of event is anisotropic, though it is still azimuthally symmetric

with respect to the original photon. This second type of event strongly favors forward and reverse

scattering, but still does not change the frequency or energy of the photon. The determining factor

between the two types is whether or not the orientation of the oscillation of the photon’s electric

field lies in the plane of scattering. When it does, the event will be anisotropic, and when it is

perpendicular to the plane of scattering the event will be isotropic. For further details see [5] and

[6].

Rayleigh scattering has a fairly strong effect on the physical measurement of skylight. These

effects can cause some degree of systematic error, especially in fields such as meteorology and

astronomy. If these effects can be properly accounted for, such systematic errors can be removed.

1.4 Applications

One of the simpler application of this model is the simulation of a solar eclipse. After configuring

the test for visible light through an atmosphere of sufficient size, simply remove all unscattered

light from the results. A lunar eclipse could be modeled in much the same way, after a lunar light

source is implemented. Given that these events are rare and short lived in any one location, it could

be useful to simulate them in advance in order to investigate what will be relevant to measure and

what you expect to find.

There are other radiation scattering scenarios that could benefit from such a model, such as

laser light or microwave radiation passing through a known medium. It should be noted however,

that fully quantum mechanical phenomena, such as interference through a diffraction grating, are

not present in this framework. It is intended that this program be utilized when macroscopic effects

5

Figure 1.4: The top part of the figure shows the intensity of scattering for the isotropic events. Themiddle section shows the distribution created by the anisotropic events. Every Rayleigh scatteringevent falls into one of these two categroies. The last part shows the two of them added together.Taken from [5].

6

are the focus of the tests. It should be feasible to extend this simulator to account for other types

of scattering, such as Mie or Compton.

7

8

Chapter 2

Methods

2.1 Monte Carlo

In a Monte Carlo test a simple situation is repeated numerous times in an attempt to draw con-

clusions or find relationships that would be arduous to calculate analytically. The analytic results,

whether known before hand or not, will be asymptotically approached with more and more itera-

tions of the test. A good example of this is found in the calculation of π. To use Monte Carlo to

calculate π, just take a squared circle, and start picking random points in the square. The ratio

of points inside and outside the circle can be used to estimate the value of π, and the greater the

number of points selected, the more closely this ratio will be to the exact value. An example of this

test is also included in this project, within the PiApproximation class. Monte Carlo is effective for

most highly repetitive processes, such as millions of photons traveling through an approximately

uniform medium.

2.2 System Requirements

All of the code in this simulator was written in C++. Some coding is required to configure the

test, so it is expected that the user have a working knowledge of C++. This simulator was run in

Centos 6. The output files were graphed using gnuplot, and the simulator does make use of the

9

gnu scientific library (GSL) both for scientific constants, and random number generation. Both of

these packages should be installed before the simulator can be compiled and run.

2.3 Simulator Conditions and Assumptions

This project consists of a simulator class which encapsulates everything else. The user is expected

to provide a main method which instantiates and configures this class. The simulator has a source,

through which all photons will be generated. The simulator also has a medium through which the

photons will scatter and a detector. The number of photons to generate and process must also be

set by the user. Note that this number represents the number of photons that will be generated,

not the number that will be captured by the detector. When run is called, a file name must be

specified to which to which all of the data will be sent. A good example of this can be found in the

ValidationSimulation.cpp file’s format method.

There are helper classes provided for matrix rotation in 3D space, and making histograms. The

output files were graphed using gnuplot, and the simulator does make use of the gnu scientific

library (GSL) both for scientific constants, and random number generation. In all cases SI units

were used to keep everything consistent. Also, the program calls for degrees over radians when

working with angles.

There are a number of random number generators (RNGs) offered in the GSL. The mt 19937

was the one used in this project. The documentation indicates that this implementation produces

numbers quickly, and that these numbers are uncorrelated. This feature was essential because

for each scattering event the simulator requires several independent random numbers. The other

important factor was that this random number generator has a very long period before repeating

numbers for any given seed. The calls to the RNG are in a singleton class, so switching implemen-

tations in the future would be practical. This implementation is located in the RandomSingleton

class.

Some of the 3D models were implemented as spheres in an effort to make them flexible and

intuitive. The medium class is a spherical cloud of whatever material is being represented. By

10

changing the size and configuration or even using multiple instances, many shapes can be approx-

imated. Detectors, too, are represented with the sub-surfaces of a sphere. Rectangular detectors

can be approximately represented by setting the angles of validation to be small and the radius to

be large.

2.4 Modeling

When implementing the photon class, it was appropriate to give a semi-classical treatment of

photons. The scenarios being modeled are assumed to be larger than a few centimeters. Photons

are assumed to travel in a straight Euclidean line at the speed of light. Therefore, there are

three coordinates associated with position and velocity (in Cartesian coordinates). The three

coordinates associated with velocity allow the user to indicate the direction. The normalization of

these coordinates is not important, only the direction indicated by their relative magnitude. Each

instance of the photon class also has a frequency, from which wavelength and energy are calculated.

There is an orientation variable for keeping track of the direction of the electric oscillation. Circular

polarization is also represented, but only as being clockwise, counter-clockwise, or not present, which

is the default. Each photon also has three coordinates associated with its point of origin.

Sources are modeled as being points from which photons are generated. Valid angles for emission

can easily be set, as well valid ranges of frequencies. The distribution of these quantities will be

uniform unless additional implementation is provided in a subclass written by the user.

As mentioned above, detectors are spherical sub-surfaces with a center position, a radius, a full

angle phi, and a half angle theta (spherical coordinates) that defines what portion of the surface

will detect photons. Currently the detectors are ideal, meaning that incident radiation has a 100%

chance of being absorbed and detected. Future work could be done to make models that showed

special sensitivity to certain frequencies or angles of incidence.

The medium class has a position, and a radius. It also has functions for calculating the free

path distance a given photon will travel through the material before a scattering event. There is

a similar function for calculating the free time a photon will travel between scattering events for

11

added flexibility. It is in the subclasses of the medium class where code to calculate the cross-section

for scattering or characteristics of the resulting photon should live, as explained below.

The Rayleigh class has the logic for the individual scattering events. As explained in [3] the

mechanism that determines whether a scattering event is isotropic is the difference between the

orientation of the electric oscillation and the plane of scattering. When these quantities are per-

pendicular the event will be isotropic, and when they are parallel the event will be anisotropic.

At all angles in between there are components in both directions and proportional chances of each

occurrence. It should be noted that the angle of scattering requires an inverse trigonometric func-

tion; otherwise the density of selected directions will be higher at the poles than in the azimuthal

directions. To achieve the correct distribution for the anisotropic case it is necessary to first apply

a normalization function that favors forward and reverse scattering before applying this correction.

The Atmosphere class is a subclass of the Rayleigh class which further specifies how the cross

section to interaction is to be found. To be useful, the free distance (or time) a photon travels

should not be uniform. In the case of Rayleigh scattering (and several other types) it should be

a Boltzmann distribution based on the cross section of interaction. Calculating the cross section

of electromagnetic radiation through different materials is an involved process, and techniques will

vary in each case. One method of calculation for visible light through air has been detailed in [2].

The article explains that given the index of refraction, the King factor of each gas (which is a term

related to calculating depolarization), and a few polynomial approximations, the cross section can

be found. By treating each of the four most common gasses in air as partial pressures with their

own distributions, four separate values are generated for the free distance from four distributions.

The shortest one is selected, and the others discarded.

The simulator class holds everything together. It has a source, a medium, a detector, and

a given number of times to generate a photon. Logic is provided to check for detection before,

during, and after the photon traverses the medium, thus giving more freedom to the user to use

any configuration they wish. There is also a check to discard any photon that leaves the medium on

a trajectory that does not go toward the detector. A test then consists of calling the main method,

which configures the members of the simulator, instantiates it, and runs it the specified number of

12

times with a given output file. All detected photons are sent to the format function, and their data

is sent to the output file.

2.5 Instructions

In order to utilize this framework, it will probably be necessary to subclass some of these general

implementations and a thorough example of how to do that is provided in the SimulateAtmosphere

program. In order to validate the model a uniform unpolarized visible light source was written, as

well as a detailed Atmosphere class that inherited some scattering logic from the Rayleigh class.

The simulator has visible light emitted toward an atmospheric medium with a radius of 100 km

toward a large detector.

If a photon is detected, the format function is called, and there is a default implementation to

send all of the data that is present in a photon after the last scattering event to the output file.

In most cases the user will want to specify what data to send to the file and in what order. In

many cases the user will also want to do some pre-processing on the data at this stage, since the

pertinent details will vary widely in each case (such as calculating the difference between a photon’s

orientation and its angle of incidence and outputting that value instead). This specification is

achieved by overriding the format function of the Simulator class to provide the relevant data in

the desired format. The scope of this function has access to all members of the Simulator class as

well as all values stored within the photon instance. In the atmosphere simulation example, data

is formatted according to frequency, various angles, degrees of polarization, and additional data is

stored in histograms to be sent to other output files later. These histograms are just objects of the

Histogram class that bin data in an array to show frequency. Check the SimulateAtmosphere class

in Appendix A for the actual implementation.

Running a simulation of only a million photons took only a few minutes, but in order to have

confidence in the results of any Monte Carlo simulator, it should run a very large number of times

(1,000,000 times should probably be considered a minimum for most cases). The simulator will

periodically indicate what percent it is toward completion, but it may still be desirable to run the

13

program as a background process for longer tests.

To run the Simulate Atmosphere program, find the directory that contains the executable in a

terminal, and type ./SimulateAtmosphere.out <number of photons to generate> <name of

test>. The main output file will be <name of test>-<host name of the computer>.out. There

will also be <name of test>-<host name of the computer>-f.out and <name of test>-<host

name of the computer>-p.out files containing histograms of the frequencies and polarizations

respectively. This means you can start the program on multiple machines using mpi or a script and

not worry about them writing to the same file. You also do not have to worry about them having

duplicate seeds, as each execution gets reseeded in the main method based on the time stamp and

the host name.

14

Chapter 3

Results

3.1 Comparison with Skylight

Dr. Joseph A. Shaw is a professor at Montana State University. He has spent many years measuring

and analyzing skylight. His findings have provided good data about the specifics of both skylight

in general and Rayleigh scattering specifically that can be used to verify the model, as found in

[7]. There are two key traits that a Rayleigh scattering model must have for skylight. First, blue

(higher frequency) light must scatter more readily and at wider angles than red (lower frequency)

light. For all unscattered photons detected, blue should be more abundant at all angles of incidence

and especially so as we approach 90 degrees. Second, Dr. Shaw references this equation,

DOLP =Ls − Lp

Ls + Lp=

1− cos2(θ)1 + cos2(θ)

=sin2(θ)

1 + cos2(θ), (3.1)

which can be used to calculate the degree of polarization of the scattered light as a function of

angle of incidence. According to equation 3.1 the scattered light should tend to be polarized in the

azimuthal direction, reaching a maximum of 100% at 90 degrees, and 33.3% at 45 degrees (which

was the condition this model checked for). Real skylight does not quite reach 100% polarization at

90 degrees of incidence because other types of scattering are present, but it does come fairly close.

Figure 3.1 shows an image taken from a cloudless sky in Hawaii. Additional explanation is found

15

Figure 3.1: This is a full sky image taken by Dr Shaw in Manua Loa, Hawaii. Note the band ofstrongly polarized light.

in [7].

Figure 3.2 shows the intensity of scattering at different angles of incidence (Shaw). Note that

the vertical axis is logarithmic. Figure 3.3 really serves two purposes. It shows that the scattering

is truly azimuthal. It also highlights the angles at which the photons tend to be detected with this

geometry.

The configuration used was effective for angles of incidence up to about 50 degrees. Much of

the data beyond that point affected by the geometry of the detector. Observe the square boundary

in figure 3.4. We can see this square pattern in the second plot at about the 50 degree mark.

The graph in figure 3.5 shows the correlations of frequency with angle of approach relative to

an unscattered beam from the source to the point on the detector where the photon made contact.

The solid line on the left side represents all of the photons in the test that did not scatter. Note also

how the number of scattered photons and the angle from source increase with frequency. Higher

frequency photons are considerably more likely to scatter more frequently and at wider angles, just

as we would expect. Compare with this diagram provided by Dr. Shaw in figure 3.6.

The number of scattered photons detected at 45 degrees were grouped by frequency in a his-

16

Figure 3.2: This plot (provided by Dr. Shaw) shows Rayleigh scattering vs scattering angle (anglebetween original and scattered directions). Unpolarized light with a wavelength of 650 nm, andparticles with a 1 nm radius.

Figure 3.3: Angle from source vs angle of polarization (relative to the z-axis)

17

Figure 3.4: Angle from source vs angle of incidence (relative to the z-axis)

18

Figure 3.5: Angle from source vs frequency

19

Figure 3.6: Wavelength dependence of Rayleigh Scattering (adapted from Dr. Shaw)

togram (figure 3.7). Photons with a higher frequency were much more likely to be detected with

a higher degree of incidence and have a higher degree of polarization in the azimuthal direction. I

believe that the drop on the right side of the graph is because of the volume and constant density of

the medium. When light travels through more atmosphere, the highest frequency light starts to get

filtered out. It may also be another manifestation of the geometry of the test. The photons with

the very highest degrees of scattering dont get detected, and these are made up almost entirely of

higher frequency photons.

The plots in figures 3.8, and 3.9, show the number of photons detected by frequency for relative

polarization and angle of incidence respectively. The main difference is that the second plot groups

all unscattered photons in the band at the bottom. So, with the unscattered band, more low

frequency photons were detected, but without it mostly high frequency photons were detected. We

can therefore infer that the medium appears blue from the perspective of the detector and also at

all other angles since blue light is what is escaping from the system.

Figure 3.10 clearly demonstrates a tendency of the photons to be polarized perpendicularly to

20

Figure 3.7: Histogram of the number of detected scattered photons sorted by frequency.

21

Figure 3.8: Frequency vs angle of polarization (from the Z-axis)

22

Figure 3.9: Frequency vs angle of incidence (from the Z-axis)

23

Figure 3.10: Angle from source vs relative polarization

their angle of approach to the detector at all valid test angles. There are two clouds of photons at

the 90 and 270 degree mark, and relatively lower densities of detected photons at 0 (and 360) and

180 degrees.

Again we can observe the distinct correlation of polarization and azimuthal angle of approach

in this generated plot. The two diagonal bands in figure 3.11 show that as you alter the direction

of approach for the incident photon, there are maximal distributions of photons whose polarization

is perpendicular to that direction and minimal distributions that are aligned or anti-aligned with

it.

Lastly the histogram in figure 3.12 was for the detected photons with an angle of incidence

of 45 degrees. It shows a clearer picture of these bands, and was used to estimate the degree of

24

Figure 3.11: Frequency vs Angle of Polarization (from the Z-axis)

25

Figure 3.12: Histogram showing the distribution of relative polarizations detected with an angle ofincidence of 45 degrees.

polarization. We expect that the degree of polarization will increase from 0 to 90 degrees. We can

use this data to infer the degree of polarization. The area under curve at angles with a positive

bias minus the area under the angles with a negative bias divided by the total area is roughly equal

to

P =(220 photons ∗ 180 degrees)− (110 photons ∗ 180 degrees)

(220 photons + 110 photons) ∗ 180 degrees)= 33.3%. (3.2)

This is the degree of polarization predicted by by equation 3.1 for 45 degrees of incidence.

26

3.2 Conclusions

We can clearly observe the first macroscopic characteristic we were looking for. As the wavelength

of an incident beam increases, it becomes less likely to scatter by that same amount raised to

the fourth power. And indeed, our results show a line very similar to the one provided by Dr.

Shaw up to about 700 THz (remember that the generated graph is reversed since the x axis in

frequency rather than wavelength). If the test were run again with a thinner atmosphere perhaps

the correlation would be even stronger. The correlation of wavelength and intensity of scattering is

affected by the change in the magnitude of the cross section rather than being inherent in any given

scattering event. In other words, the scatter function in the file Rayleigh.cpp affects all photons

the same, regardless of their frequency (or wavelength). The getFreeDistance function on the other

hand, gives much lower values for photons with higher frequency because the cross section used to

calculate this distance is highly frequency dependent.

It is actually the selection mechanism for isotropic scattering in individual events that causes

the azimuthal polarization pattern. At no point in the code do we cause a biased change to a

photon’s polarization. In the Rayleigh class the scattering function does selectively change the

linear polarization on a photon, but only by giving it a new evenly distributed random value. In

earlier iterations of this model various biased changes were tested, but the results always tended

to yield either too much or the wrong kind of linear polarization. By randomly changing the

orientation of a photon for anisotropic scattering and leaving unchanged for isotropic scattering, a

very close match to the predicted degree of linear polarization at 45 degrees of incidence is achieved,

and that polarization is in exactly the right direction.

3.3 Future Research

This framework can be used to estimate the effects of Rayleigh scattering for other radiation related

projects. If the distribution of generated light and the variable density of the atmosphere were added

then a simulation could be made to give quantitative measurements of the sky, such as what is

the exact color we see when the sun reaches a certain angle above the horizon. If the type and

27

thickness of the medium are known, as well as the exact distribution of incoming light, accurate

predictions can be made about how the Rayleigh scattered light will be reflected. It may also be

useful to make predictions about the prevailing conditions in the upcoming solar eclipse. With a

little work this model can be extended to model other types of scattering as well.

This simulator could be made to run in parallel on the Linux cluster in the Romney building

by making use of the message passing interface (mpi). This would allow detailed tests to be run

on the scale of hundreds of millions of photons in a manageable amount of time. It could also be

improved by creating an interface that would allow the user to configure and run a test without

having to code a main method, even if it came at the cost of a little flexibility.

28

Bibliography

[1] Scattering of radiation with polarization. University of Maryland.

[2] Barry A. Bodhaine, Norman B. Wood, Ellsworth G. Dutton, and James R. Slusser. On rayleighoptical depth calculations. Journal of Atmospheric and Oceanic Technology, 16:1854–1861,1999.

[3] H. Van de Hulst. Multiple Light Scattering. Elsevier inc, Woodbury, NY, 1980.

[4] Vladamir Kuzmina and Igor Meglinski. Helicity fip of the backscattered circular polarized light.Proc of SPIE, 7537.

[5] K. N. Liou. An Introduction to Atmospheric Radiation. Academic Press, San Diego, CA, secondedition, 2002.

[6] Nathan J. Pust and Joseph A. Shaw. Dual-eld imaging polarimeter using liquid crystal variableretarders. Applied Optics, 45.

[7] Joseph A. Shaw. Remote sensing systems. Montana State University.

29

30

Appendix A

Simulator Source Code

Atmosphere.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Atmosphere Header∗ 1−9−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f ATMOSPHERE H#d e f i n e ATMOSPHERE H

#inc lude <g s l / gs l const num . h>#inc lude ” Rayle igh . h”#inc lude ”Photon . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Atmosphere Class∗ A medium through which photons may pass .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Atmosphere : pub l i c Rayle igh{

p r i v a t e :enum Gas {N2 , O2, AR, CO2} ;// Perc i ent compos i t ion by volumeconst s t a t i c double COMPOSITION [ 4 ] ;// Density by mole/mˆ3const s t a t i c double DENSITY = 22414 ;const s t a t i c double NA = GSL CONST NUM AVOGADRO;

double ge tCros sSec t i on ( const Photon &photon , Gas gas ) const ;double getKingFactor ( const Photon &photon , Gas gas ) const ;double getDens i ty (Gas gas ) const ;

31

double ge tRe f ra c t i v e Index ( const Photon &photon ) const ;pub l i c :

Atmosphere ( ) : Rayle igh ( ) {} ;Atmosphere ( Point po int ) : Rayle igh ( po int ) {} ;Atmosphere ( double ∗ coord inate ) : Rayle igh ( coord inate ) {} ;Atmosphere ( double rad iu s ) : Rayle igh ( rad iu s ) {} ;Atmosphere ( Point point , double rad iu s ) : Rayle igh ( point , r ad iu s ) {} ;Atmosphere ( double ∗ coord inate , double rad iu s ) :

Rayle igh ( coord inate , r ad iu s ) {} ;Atmosphere ( const Medium & medium) : Rayle igh (medium) {} ;v i r t u a l double getFreeDis tance ( const Photon &photon ) const ;v i r t u a l double getFreeTime ( const Photon &photon ) const ;

} ;#e n d i f

32

Atmosphere.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Atmosphere Class∗ 1−9−2015∗ For more in fo rmat ion see :∗ Bodhaine , B. A. , Wood, N. B. , Dutton , E. G. , and S lu s s e r ,∗ J . R . : On Rayle igh o p t i c a l depth c a l c u l a t i o n s , J . Atm.∗ Ocean Technol . , 16 , 1854 1 8 6 1 , 1999 .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <math . h>#inc lude ”Atmosphere . h”#inc lude ”Photon . h”us ing namespace std ;

const double Atmosphere : : COMPOSITION[ 4 ] = { . 78084 , . 20946 , . 00934 , . 0 0 036} ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Density∗ Get the dens i ty o f the gas (% by volume ∗ mole/mˆ3 ∗ NA) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : getDens i ty (Gas gas ) const{

re turn COMPOSITION[ gas ] ∗ DENSITY ∗ NA;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Cross Sec t i on∗ The c r o s s s e c t i o n i s used in determining how f a r a photon∗ t r a v e l s be f o r e being s c a t t e r e d .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : g e tCros sSec t i on ( const Photon &photon , Gas gas ) const{

double r i = ge tRe f rac t i v e Index ( photon ) ;double r i 2 = pow( r i , 2 ) ; // r i ˆ2double dens i ty = getDens i ty ( gas ) ; // molecu le s per mˆ3double k f = getKingFactor ( photon , gas ) ;r e turn 24 ∗ pow(M PI , 3) ∗ pow( r i 2 − 1 , 2) / (pow( photon . getWavelength ( ) , 4)∗ pow( dens i ty , 2) ∗ pow( r i 2 + 2 , 2 ) ) ∗ kf ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗33

∗ Get King Factor∗ The king f a c t o r i s r e l a t e d to the d e p o l a r i z a t i o n constant∗ o f a gas , and i s need to c a l c u l a t e the c r o s s s e c t i o n . I t∗ v a r i e s from one gas to another .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : getKingFactor ( const Photon &photon , Gas gas ) const{

double k ingFactor = 0 ;switch ( gas ){

case N2 :k ingFactor = 1.034 + .000317 / pow( photon . getWavelength ( ) , 2 ) ;break ;

case O2 :k ingFactor = 1.096 + .001385 / pow( photon . getWavelength ( ) , 2) +

.0001448 / pow( photon . getWavelength ( ) , 4 ) ;break ;

case AR:kingFactor = 1 . 0 0 ;break ;k ingFactor = 1 . 1 5 ;

case CO2:break ;

}re turn kingFactor ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get R e f r a c t i v e Index∗ The r e f r a c t i v e index o f a i r f o r a g iven f requency .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : g e tRe f r a c t i v e Index ( const Photon &photon ) const{

double one over lambda2 = pow( photon . getWavelength ( ) , −2);r e turn (8 .6051 + 2480990 / (132 .274 − one over lambda2 ) + 17455.7 /

(39 .32957 − one over lambda2 ) ) ∗ .00000001 + 1 ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Free Distance∗ Return the d i s t anc e a photon w i l l t r a v e l be f o r e an∗ i n t e r a c t i o n ( does not need to be the same each time ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : ge tFreeDis tance ( const Photon &photon ) const

34

{// c a l c u l a t e the d i s t anc e the photon w i l l t r a v e l becuase o f// each p a r t i a l p r e s su r e o f gasdouble d i s t anc e [ 4 ] = {0 , 0 , 0 , 0} ;// based on a c o r r e c t random d i s t r i b u t i o n that i s// c a l c u l a t e d independent ly from the other d i s t a n c e sd i s t anc e [ 0 ] = − ( l og (1 − getRS ( ) . rand ( ) ) ) / ( getDens i ty (N2) ∗

ge tCros sSec t i on ( photon , N2 ) ) ;d i s t anc e [ 1 ] = − ( l og (1 − getRS ( ) . rand ( ) ) ) / ( getDens i ty (O2) ∗

ge tCros sSec t i on ( photon , N2 ) ) ;d i s t anc e [ 2 ] = − ( l og (1 − getRS ( ) . rand ( ) ) ) / ( getDens i ty (AR) ∗

ge tCros sSec t i on ( photon , N2 ) ) ;d i s t anc e [ 3 ] = − ( l og (1 − getRS ( ) . rand ( ) ) ) / ( getDens i ty (CO2) ∗

ge tCros sSec t i on ( photon , N2 ) ) ;i n t n = 0 ;i n t i ;// s e l e c t the s h o r t e s t o f the se d i s t a n c e sf o r ( i = 1 ; i < 4 ; i++){

i f ( d i s t ance [ i ] < d i s t anc e [ n ] ){

n = i ;}

}re turn d i s t anc e [ n ] ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Free Time∗ Return the time a photon w i l l t r a v e l b e f o r e an∗ i n t e r a c t i o n ( does not need to be the same each time ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Atmosphere : : getFreeTime ( const Photon &photon ) const{

re turn getFreeDis tance ( photon ) / Photon : : getC ( ) ;}

35

Detector.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Detector Header∗ 1−23−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f DETECTOR H#d e f i n e DETECTOR H

#inc lude ”Photon . h”#inc lude ” Point . h”#inc lude ” Sol idAngle . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Detector Class∗ This c l a s s s imu la t e s l i g h t de t e c t o r .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Detector{

p r i v a t e :Point l o c a t i o n ;Point la s tContac t ; // Last r e g i s t e r e d po int o f contactSo l idAngle theta ; //0 to p iSo l idAngle phi ; //0 to 2 p idouble rad iu s ;double numDetected ;bool i sNarrowing ( const Point & o r i g i n a l , const Point & next ) const ;double getMinDistance ( const Photon & photon , double & time ) const ;Point getContact ( const Photon & photon , double & minTime ) ;

pub l i c :Detector ( ) : theta ( f a l s e ) , phi ( t rue ) { l o c a t i o n ; l a s tContac t ; r ad iu s = 1 ;

numDetected = 0 ; } ;Detector ( double ∗ coord inate , double thetaMin , double thetaMax ,

double phiMin , double phiMax , double rad iu s ) ;Detector ( const Detector & de t e c t o r ) : l o c a t i o n ( de t e c t o r . getLocat ion ( ) ) ,

l a s tContac t ( de t e c t o r . getLastContact ( ) ) , theta ( de t e c t o r . getTheta ( ) ) ,phi ( d e t e c t o r . getPhi ( ) ){ rad iu s = de t e c t o r . getRadius ( ) ; numDetected = 0 ; } ;

Point getLocat ion ( ) const { re turn l o c a t i o n ; } ; // get the l o c a t i o nSol idAngle getTheta ( ) const { re turn theta ; } ; // get the v e r t i c a l ang leSo l idAngle getPhi ( ) const { re turn phi ; } ; // get the h o r i z o n t a l ang ledouble getRadius ( ) const { re turn rad iu s ; } ;double getNumDetected ( ) const { re turn numDetected ; } ;

36

Point getLastContact ( ) const { re turn la s tContac t ; } ;void s e tLoca t i on ( i n t min , double max) { theta . setMin ( min ) ;

theta . setMax (max ) ; } ;void setTheta ( double min , double max) { theta . setMin ( min ) ;

theta . setMax (max ) ; } ;void setPhi ( double min , double max) {phi . setMin ( min ) ; phi . setMax (max ) ; } ;void setRadius ( double r ) { i f ( r >= 0) rad iu s = r ; } ;void setNumDetected ( double n) { i f (n >= 0) numDetected = n ; } ;v i r t u a l bool detec ted ( const Photon & photon , double amount ,

bool isTime = true ) ;} ;#e n d i f

37

Detector.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Detector Class∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude ” Detector . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Detector∗ I n i t i a l i z e everyth ing . Phi must be a f u l l angle , and∗ theta a h a l f ang le .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Detector : : Detector ( double ∗ coord inate , double thetaMin , double thetaMax ,

double phiMin , double phiMax , double rad iu s ) : l a s tContac t ( ) ,theta ( thetaMin , thetaMax , f a l s e ) , phi ( phiMin , phiMax , t rue )

{f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

l o c a t i o n . se tCoord inate ( i , coo rd inate [ i ] ) ;}th i s−>rad iu s = rad iu s ;numDetected = 0 ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ I s Narrowing∗ Determine whether the next po int i s narrowing the minimum∗ d i s t anc e to the l o c a t i o n o f t h i s detector , even i f i t i s∗ f a r t h e r away than the o r i g i n a l po int . The check i s made∗ by s e e i n g i f the d i s t anc e between the o r i g i n a l and next∗ po in t s squared p lus the d i s t anc e from the de t e c t o r to the∗ o r i g i n a l squared i s l e s s than or equal to the d i s t anc e∗ between the next po int and the de t e c t o r squared∗ ( pythagorean theorem ) . I f the l o c a t i o n o f t h i s d e t e c t o r∗ and both o f the se po in t s were to l i e on a s t r a i g h t l i n e∗ in 3d space , t h i s func t i on would re turn true i f the∗ de t e c t o r were between the other two po in t s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/bool Detector : : i sNarrowing ( const Point & o r i g i n a l , const Point & next ) const

38

{double dOr ig ina l = getLocat ion ( ) . ge tDi s tance ( o r i g i n a l ) ;double dNext = getLocat ion ( ) . ge tDi s tance ( next ) ;double dCheck = o r i g i n a l . ge tDi s tance ( next ) ;r e turn pow( dOrig ina l , 2) + pow( dCheck , 2) >= pow( dNext , 2 ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Min Distance∗ Calcu la te the minimum d i s t anc e from the cente r o f t h i s∗ de t e c t o r that a photon w i l l be at any given po int along∗ the path i s w i l l t r a v e r s e in the g iven time . Update the∗ amout o f time i t took to get the re . I f 0 or the f u l l time∗ are the optimal va lue s in the g iven range , r e turn those∗ va lue s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Detector : : getMinDistance ( const Photon & photon , double & time ) const{

Photon p = photon ; // s i n c e we are not going to change photonp . advance ( time ) ; // move the photon the f u l l time along i t s t r a j e c t o r ydouble d I n i t i a l = photon . getLocat ion ( ) . ge tDi s tance ( l o c a t i o n ) ; // 0 timedouble dFinal = p . getLocat ion ( ) . ge tDi s tance ( l o c a t i o n ) ; // f u l l timei f ( d I n i t i a l < dFinal && ! isNarrowing ( photon . getLocat ion ( ) , p . getLocat ion ( ) ) ){

// the c l o s e s t po int i s behind the photontime = 0 ;re turn d I n i t i a l ;

}e l s e i f ( d I n i t i a l > dFinal && ! isNarrowing (p . getLocat ion ( ) ,

photon . getLocat ion ( ) ) ){

// the c l o s e s t po int i s f a r t h e r ahead than the photon had time to t r a v e l tore turn dFinal ;

}// norma l i za t i on constant f o r the componenets o f the v e l o c i t y o f the photondouble n = p . normal ize ( ) ;double vx = photon . g e tVe l o c i t y ( ) [ 0 ] ∗ n ;double vy = photon . g e tVe l o c i t y ( ) [ 1 ] ∗ n ;double vz = photon . g e tVe l o c i t y ( ) [ 2 ] ∗ n ;double px = photon . getLocat ion ( ) [ 0 ] ;double py = photon . getLocat ion ( ) [ 1 ] ;double pz = photon . getLocat ion ( ) [ 2 ] ;double lx = getLocat ion ( ) [ 0 ] ;double ly = getLocat ion ( ) [ 1 ] ;

39

double l z = getLocat ion ( ) [ 2 ] ;// t h i s equat ion i s der ived by r e a l i z i n g the dot product o f the v e l o c i t y// o f the photon and the vec to r from the photon to the detector ’ s l o c a t i o n// must be zero at the po int we are s e ek ingtime = ( vx ∗ ( l x − px ) + vy ∗ ( l y − py ) + vz ∗ ( l z − pz ) ) / (pow( vx , 2) +

pow( vy , 2) + pow( vz , 2 ) ) ;p = photon ;p . advance ( time ) ;r e turn p . getLocat ion ( ) . ge tDis tance ( getLocat ion ( ) ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Contact∗ Calcu la te the po int o f contact the photon w i l l make .∗ Assume that the minTime i s the time to get to the c l o s e s t∗ po int along the path , and that the photon w i l l be at that∗ po int be with in the rad iu s . Set the c a l c u l a t e d po int as∗ the l a s t contact r e g i s t e r e d to t h i s d e t e c t o r .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Point Detector : : getContact ( const Photon & photon , double & minTime){

Photon p = photon ;i n t n = 1 ;double t = minTime / pow(2 , n++);double tPrev = 0 ;double d = 0 ;double dPrev = photon . getLocat ion ( ) . ge tDis tance ( l o c a t i o n ) ;// binary searchwhi l e (d < rad iu s && t != tPrev ){

p = photon ;p . advance ( t ) ;d = p . getLocat ion ( ) . ge tDi s tance ( l o c a t i o n ) ;t = tPrev ;i f (d < rad iu s ) // we are i n s i d e the radius , t should be sma l l e r{

t −= minTime / pow(2 , n++);dPrev = d ;

}e l s e i f (d > rad iu s ) // we are ou t s i d e the radius , t should be b igge r{

t += minTime / pow(2 , n++);d = dPrev ;

}

40

}l a s tContac t = p . getLocat ion ( ) ; // keep track o f t h i s po intre turn la s tContac t ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Detected∗ Determine whether the g iven photon w i l l be absorbed by∗ the de t e c t o r . Note : i f t h i s method re tu rn s t rue then the∗ po int o f l a s t contact w i l l have been r e s e t .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/bool Detector : : de tec ted ( const Photon & photon , double amount , bool isTime ){

i f ( photon . getLocat ion ( ) . ge tDi s tance ( l o c a t i o n ) < rad iu s ){

// a l r eady past the de t e c t o rre turn f a l s e ;

}double time ;i f ( isTime ) // they gave us time to t r a v e l{

time = amount ;}e l s e // they gave us d i s t anc e to t r a v e l{

time = amount / Photon : : getC ( ) ;}double minTime = time ;double minDistance = getMinDistance ( photon , minTime ) ;i f ( minDistance > rad iu s ) // we never get c l o s e enough{

re turn f a l s e ;}Point contact = getContact ( photon , minTime ) ; // get where we h i tdouble r = s q r t (pow( contact . getCoordinate ( 0 ) , 2) +

pow( contact . getCoordinate ( 1 ) , 2 ) ) ; // s q r t ( xˆ2 + y ˆ2)// ang l e s o f po int o f contact from the d e t e c t o r s l o c a t i o ndouble anglePhi = atan2 ( contact . getCoordinate (1 ) − l o c a t i o n . getCoordinate ( 1 ) ,

contact . getCoordinate (0 ) − l o c a t i o n . getCoordinate ( 0 ) ) ∗ 180 / M PI ;double angleTheta = atan2 ( r , contact . getCoordinate (2 ) −

l o c a t i o n . getCoordinate ( 2 ) ) ∗ 180 / M PI ;// t rue i f the po int was in v a l i d rangereturn phi . i sInRange ( anglePhi ) && theta . isInRange ( angleTheta ) ;

}

41

Histogram.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Histogram Header∗ 3−25−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f HISTOGRAM H#d e f i n e HISTOGRAM H

#inc lude <iostream>#inc lude <s t r i ng>

us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Histogram Class∗ This c l a s s keeps t rack o f the number o f e n t r i e s in∗ equa l l y s i z e d conse cu t i v e b ins .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Histogram{

protec ted :i n t ∗ bins ;unsigned i n t numBins ;double b inS i z e ;double i n i t i a l ;

pub l i c :Histogram ( unsigned i n t numBins , double b inS ize , double i n i t i a l ) ;Histogram ( const Histogram & h ) ;˜Histogram ( ) { d e l e t e [ ] b ins ; } ;i n t ∗ getBins ( ) const { re turn b ins ; } ;unsigned i n t getNumBins ( ) const { re turn numBins ; } ;double ge tB inS i ze ( ) const { re turn b inS i z e ; } ;double g e t I n i t i a l ( ) const { re turn i n i t i a l ; } ;s t r i n g toS t r i ng ( ) const ;double operator [ ] ( i n t i ) const { i f ( i >= 0 && i < numBins ) re turn b ins [ i ] ;

e l s e re turn 0 ; } ;double operator [ ] ( double n) const { i n t i = ( i n t ) ( ( n − i n i t i a l ) / b inS i z e ) ;

i f ( i >= 0 && i < numBins ) re turn b ins [ i ] ; e l s e re turn 0 ; } ;void operator<<(double n) { i n t i = ( i n t ) ( ( n − i n i t i a l ) / b inS i z e ) ;

i f ( i >= 0 && i < numBins ) b ins [ i ]++;} ;} ;#e n d i f

42

Histogram.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Histogram Source∗ 3−25−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <sstream>#inc lude ”Histogram . h”

us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Constructor∗ I n i t i a l i z e the va lue s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Histogram : : Histogram ( unsigned i n t numBins , double b inS ize , double i n i t i a l ){

th i s−>numBins = numBins ;th i s−>b inS i z e = b inS i z e ;th i s−> i n i t i a l = i n i t i a l ;b ins = new i n t [ numBins ] ;f o r ( i n t i = 0 ; i < numBins ; i++){

bins [ i ] = 0 ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Copy Constructor∗ Make an independent copy o f h .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Histogram : : Histogram ( const Histogram & h){

th i s−>numBins = h . numBins ;th i s−>b inS i z e = h . b inS i z e ;th i s−> i n i t i a l = h . i n i t i a l ;b ins = new i n t [ h . numBins ] ;f o r ( i n t i = 0 ; i < h . numBins ; i++){

th i s−>bins [ i ] = h . b ins [ i ] ;}

}

43

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ To St r ing∗ Return ”bin− i n i t i a l bin−f i n a l bin−count\n” f o r a l l b ins .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/s t r i n g Histogram : : t oS t r i ng ( ) const{

s t r i ng s t r eam stream ;f o r ( i n t i = 0 ; i < numBins ; i++){

stream << ( i n i t i a l + i ∗ b inS i z e ) << ” ” << ( i n i t i a l + ( i + 1) ∗ b inS i z e )<< ” ” << bins [ i ] << ”\n ” ;

}re turn stream . s t r ( ) ;

}

44

makefile

############################################################ S c a t t e r i n g# James Nelson# 1−8−15###########################################################a l l : PiApproximation . out TestDetector . out TestSource . out

Tes tV i s ib l eSource . out TestPhoton . out TestMedium . outTestRayle igh . out TestPoint . out TestSo l idAngle . outTestRotat ion . out TestRandomSingleton . out TestAtmosphere . outTestS imulat ion . out TestHistogram . out SimulateAtmosphere . out

echo ”Done”

PiApproximation : PiApproximation . out. / PiApproximation . out

TestDetector : TestDetector . out. / TestDetector . out

TestSource : TestSource . out. / TestSource . out

Tes tV i s ib l eSource : Tes tV i s ib l eSource . out. / Tes tV i s ib l eSource . out

TestPhoton : TestPhoton . out. / TestPhoton . out

TestMedium : TestMedium . out. / TestMedium . out

TestRayle igh : TestRayle igh . out. / TestRayle igh . out

TestPoint : TestPoint . out. / TestPoint . out

TestSo l idAngle : TestSo l idAngle . out. / TestSo l idAngle . out

TestRotat ion : TestRotat ion . out. / TestRotat ion . out

TestRandomSingleton : TestRandomSingleton . out. / TestRandomSingleton . out

TestAtmosphere : TestAtmosphere . out. / TestAtmosphere . out

TestS imulat ion : TestS imulat ion . out. / TestS imulat ion . out

TestHistogram : TestHistogram . out. / TestHistogram . out

SimulateAtmosphere : SimulateAtmosphere . out. / SimulateAtmosphere . out

45

PiApproximation . out : PiApproximation . o Source . o Detector . oSo l idAngle . o Photon . o Point . o RandomSingleton . o

g++ −o PiApproximation . out PiApproximation . o Source . oDetector . o So l idAngle . o Photon . o Point . oRandomSingleton . o − l g s l − l g s l c b l a s

TestDetector . out : TestDetector . o Detector . o So l idAngle . oPhoton . o Point . o

g++ −o TestDetector . out TestDetector . o Detector . oSo l idAngle . o Photon . o Point . o RandomSingleton . o− l g s l − l g s l c b l a s

TestSource . out : TestSource . o Source . o So l idAngle . o Photon . oPoint . o RandomSingleton . o

g++ −o TestSource . out TestSource . o Source . o So l idAngle . oPhoton . o Point . o RandomSingleton . o − l g s l − l g s l c b l a s

Tes tV i s ib l eSource . out : Tes tV i s ib l eSource . o V i s i b l eSou r c e . oSource . o So l idAngle . o Photon . o Point . o RandomSingleton . o

g++ −o Tes tV i s ib l eSource . out Tes tV i s ib l eSource . oV i s i b l eSou r c e . o Source . o So l idAngle . o Photon . o Point . oRandomSingleton . o − l g s l − l g s l c b l a s

TestPhoton . out : TestPhoton . o Photon . o Point . og++ −o TestPhoton . out TestPhoton . o Photon . o Point . o

TestMedium . out : TestMedium . o Photon . o Medium . o Point . oRotation . o RandomSingleton . o

g++ −o TestMedium . out TestMedium . o Photon . o Point . oMedium . o Rotation . o RandomSingleton . o − l g s l − l g s l c b l a s

TestRayle igh . out : TestRayle igh . o Photon . o Rayle igh . o Point . oMedium . o Rotation . o RandomSingleton . o

g++ −o TestRayle igh . out TestRayle igh . o Photon . o Point . oRayle igh . o Medium . o Rotation . o RandomSingleton . o− l g s l − l g s l c b l a s

TestAtmosphere . out : TestAtmosphere . o Photon . o Rayle igh . o Point . oMedium . o Rotation . o RandomSingleton . o Atmosphere . o

g++ −o TestAtmosphere . out TestAtmosphere . o Photon . o Point . oRayle igh . o Medium . o Rotation . o RandomSingleton . oAtmosphere . o − l g s l − l g s l c b l a s

TestPoint . out : TestPoint . o Point . og++ −o TestPoint . out TestPoint . o Point . o

TestSo l idAngle . out : TestSo l idAngle . o So l idAngle . og++ −o TestSo l idAngle . out TestSo l idAngle . o So l idAngle . o

TestRotat ion . out : TestRotat ion . o Rotation . og++ −o TestRotat ion . out TestRotat ion . o Rotation . o

TestRandomSingleton . out : TestRandomSingleton . o RandomSingleton . og++ −o TestRandomSingleton . out TestRandomSingleton . o

RandomSingleton . o − l g s l − l g s l c b l a s

46

TestSimulat ion . out : TestS imulat ion . o Simulat ion . o Medium . oRayle igh . o Atmosphere . o Source . o V i s i b l eSou r c e . o Detector . oPhoton . o Point . o So l idAngle . o Rotation . o RandomSingleton . o

g++ −o TestSimulat ion . out TestS imulat ion . o Simulat ion . oMedium . o Rayle igh . o Atmosphere . o Source . o V i s i b l eSou r c e . oDetector . o Photon . o Point . o So l idAngle . o Rotation . oRandomSingleton . o − l g s l − l g s l c b l a s

TestHistogram . out : TestHistogram . o Histogram . og++ −o TestHistogram . out TestHistogram . o Histogram . o

SimulateAtmosphere . out : SimulateAtmosphere . o Va l idat i onS imulat i on . oSimulat ion . o Medium . o Rayle igh . o Atmosphere . o Source . oV i s i b l eSou r c e . o Detector . o Photon . o Point . o So l idAngle . oRotation . o RandomSingleton . o Histogram . o

g++ −o SimulateAtmosphere . out SimulateAtmosphere . oVa l idat ionS imula t i on . o Simulat ion . o Medium . o Rayle igh . oAtmosphere . o Source . o V i s i b l eSou r c e . o Detector . o Photon . oPoint . o So l idAngle . o Rotation . o RandomSingleton . oHistogram . o − l g s l − l g s l c b l a s

PiApproximation . o : PiApproximation . cppg++ −c PiApproximation . cpp

Detector . o : Detector . h Detector . cpp Sol idAngle . h So l idAngle . cppPoint . h Point . cpp Photon . h Photon . cpp

g++ −c Detector . cppTestDetector . o : Detector . h TestDetector . cpp Photon . h Photon . cpp

g++ −c TestDetector . cppSource . o : Source . h Source . cpp Sol idAngle . h So l idAngle . cpp Point . h

Point . cpp Photon . h Photon . cpp RandomSingleton . hRandomSingleton . cpp

g++ −c Source . cppTestSource . o : Source . h TestSource . cpp Photon . h Photon . cpp

g++ −c TestSource . cppV i s i b l eSou r c e . o : V i s i b l eSou r c e . h V i s i b l eSou r c e . cpp Source . h

Source . cpp Sol idAngle . h So l idAngle . cpp Point . h Point . cppPhoton . h Photon . cpp RandomSingleton . h RandomSingleton . cpp

g++ −c V i s i b l eSou r c e . cppTes tV i s ib l eSource . o : V i s i b l eSou r c e . h Tes tV i s ib l eSource . cpp

Source . h Source . cpp Photon . h Photon . cppg++ −c Tes tV i s ib l eSource . cpp

Photon . o : Photon . h Photon . cppg++ −c Photon . cpp

TestPhoton . o : Photon . h TestPhoton . cpp Point . h Point . cppg++ −c TestPhoton . cpp

Medium . o : Medium . h Medium . cpp Photon . h Point . h Rotation . hRotation . cpp

47

g++ −c Medium . cppTestMedium . o : Medium . h TestMedium . cpp Photon . h Point . h

Rotation . h Rotation . cppg++ −c TestMedium . cpp

Rayle igh . o : Rayle igh . h Rayle igh . cpp Medium . h Medium . cppPhoton . h Point . h

g++ −c Rayle igh . cppTestRayle igh . o : Rayle igh . h TestRayle igh . cpp Medium . h Medium . cpp

Photon . h Point . hg++ −c TestRayle igh . cpp

Point . o : Point . h Point . cppg++ −c Point . cpp

TestPoint . o : Point . h TestPoint . cppg++ −c TestPoint . cpp

Sol idAngle . o : So l idAngle . h So l idAngle . cppg++ −c So l idAngle . cpp

TestSo l idAngle . o : So l idAngle . h TestSo l idAngle . cppg++ −c TestSo l idAngle . cpp

Rotation . o : Rotation . h Rotation . cppg++ −c Rotation . cpp

TestRotat ion . o : Rotation . h TestRotat ion . cppg++ −c TestRotat ion . cpp

RandomSingleton . o : RandomSingleton . h RandomSingleton . cppg++ −c RandomSingleton . cpp

TestRandomSingleton . o : RandomSingleton . hTestRandomSingleton . cpp

g++ −c TestRandomSingleton . cppAtmosphere . o : Atmosphere . h Atmosphere . cpp

g++ −c Atmosphere . cppTestAtmosphere . o : Atmosphere . h TestAtmosphere . cpp

g++ −c TestAtmosphere . cppSimulat ion . o : S imulat ion . h Simulat ion . cpp

g++ −c Simulat ion . cppTestSimulat ion . o : S imulat ion . h TestSimulat ion . cpp

g++ −c TestS imulat ion . cppHistogram . o : Histogram . h Histogram . cpp

g++ −c Histogram . cppTestHistogram . o : Histogram . h TestHistogram . cpp

g++ −c TestHistogram . cppVa l idat ionS imula t i on . o : Va l idat ionS imulat i on . h

Va l idat ionS imula t i on . cpp Simulat ion . h Simulat ion . cppHistogram . h Histogram . cpp

g++ −c Va l idat i onS imulat i on . cppSimulateAtmosphere . o : Va l idat i onS imulat i on . h Simulat ion . h

48

Histogram . h SimulateAtmosphere . cppg++ −c SimulateAtmosphere . cpp

copy :cp ∗ . cpp ∗ . h make f i l e . . / Backup / .

c l ean :rm ∗ . o ∗ . out

49

Medium.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Medium Header∗ 1−8−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f MEDIUM H#d e f i n e MEDIUM H

#inc lude ”Photon . h”#inc lude ” Point . h”#inc lude ” Rotation . h”#inc lude ”RandomSingleton . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Medium Class∗ This c l a s s s imu la t e s a medium f o r photons to pass∗ through . Chi ldren c l a s s e s can absorb and s c a t t e r them as∗ d e s i r e d .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Medium{

protec ted :Point l o c a t i o n ;Rotation r o t a t e r ;double rad iu s ;

pub l i c :Medium ( ) : r o t a t e r (1 , 0 , 0) { rad iu s = 1 . 0 ; } ;Medium( Point po int ) : l o c a t i o n ( po int ) , r o t a t e r (1 , 0 , 0) { rad iu s = 1 . 0 ; } ;Medium( double ∗ coord inate ) : l o c a t i o n ( coord inate ) , r o t a t e r (1 , 0 , 0)

{ rad iu s = 1 . 0 ; } ;Medium( double rad iu s ) : r o t a t e r (1 , 0 , 0) { th i s−>rad iu s = rad iu s ; } ;Medium( Point point , double rad iu s ) : l o c a t i o n ( po int ) , r o t a t e r (1 , 0 , 0)

{ th i s−>rad iu s = rad iu s ; } ;Medium( double ∗ coord inate , double rad iu s ) : l o c a t i o n ( coord inate ) ,

r o t a t e r (1 , 0 , 0) { th i s−>rad iu s = rad iu s ; } ;Medium( const Medium & medium) : l o c a t i o n (medium . getLocat ion ( ) ) ,

r o t a t e r (1 , 0 , 0) { th i s−>rad iu s = medium . getRadius ( ) ; } ;Point getLocat ion ( ) const { re turn l o c a t i o n ; } ; // get the cur rent l o c a t i o ndouble getRadius ( ) const { re turn rad iu s ; } ;Rotation getRotater ( ) const { re turn r o t a t e r ; } ;v i r t u a l double getFreeDis tance ( const Photon &photon ) const ;v i r t u a l double getFreeTime ( const Photon &photon ) const ;

50

s t a t i c RandomSingleton & getRS ( ) { re turn RandomSingleton : : g e t In s tance ( ) ; } ;void s e tLoca t i on ( i n t i , double n ) ;void se tRotate r ( double x , double y , double z ) { r o t a t e r . s e tAx i s (0 , x ) ;

r o t a t e r . s e tAx i s (1 , y ) ; r o t a t e r . s e tAx i s (2 , z ) ; } ;void setRadius ( double r ) { i f ( r >= 0) rad iu s = r ; } ;bool isInMedium ( const Point &point ) const

{ re turn po int . ge tDi s tance ( l o c a t i o n ) <= rad iu s ; } ;v i r t u a l void s c a t t e r ( Photon &photon ) ;

} ;#e n d i f

51

Medium.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Medium Class∗ 1−8−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <c s t d l i b>#inc lude ”Medium . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Locat ion∗ Set a s p e c i f i c coo rd ina te o f the l o c a t i o n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Medium : : s e tLoca t i on ( i n t i , double n){

i f ( i >= 0 && i < Point : : SIZE )l o c a t i o n . se tCoord inate ( i , n ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Free Distance∗ Return the d i s t anc e a photon w i l l t r a v e l be f o r e an∗ i n t e r a c t i o n ( does not need to be the same each time ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Medium : : getFreeDis tance ( const Photon &photon ) const{

re turn rand ( ) ; // r e w r i t e t h i s f o r c h i l d r e n c l a s s e s}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Free Time∗ Return the time a photon w i l l t r a v e l b e f o r e an∗ i n t e r a c t i o n ( does not need to be the same each time ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Medium : : getFreeTime ( const Photon &photon ) const{

re turn rand ( ) ; // r e w r i t e t h i s f o r c h i l d r e n c l a s s e s}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Sca t t e r∗ This i s the ba s i c func t i on to change the v e l o c i t y , and

52

∗ p o s s i b l y the f requency and p l a r i z a t i o n o f a g iven∗ photon . Should c a l l increment on the photon .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Medium : : s c a t t e r ( Photon &photon ){

i f ( isInMedium ( photon . getLocat ion ( ) ) ){

f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

photon . s e t V e l o c i t y ( i , rand ( ) % 3 − 1 ) ;}photon . increment ( ) ;

}}

53

Photon.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Photon Header∗ 1−8−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f PHOTON H#d e f i n e PHOTON H

#inc lude <s t r i ng>#inc lude ” Point . h”#inc lude <g s l / g s l cons t mksa . h>us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon Class∗ This c l a s s s imu la t e s a photon and keeps t rack o f∗ r e l e v a n t data . Al l d i s t a n c e s are in meters , a l l t imes are∗ in seconds , a l l ang l e s are in degrees , and a l l e n e r g i e s∗ are in Jou l e s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Photon{

p r i v a t e :Point l o c a t i o n ; // where the photon i sPoint o r i g i n ; // where the photon s t a r t e dPoint v e l o c i t y ; // which way the photon i s goingdouble f requency ; // keeps t rack o f wavelength and energy a l s o

// ang le o f E f i e l d o s c i l l a t i o n to a r b i t r a r y axis ,// as viewed from the source

double o r i e n t a t i o n ;double phase ; // phase between E and B maximai n t c i r c u l a r P o l a r i z a t i o n ; //1 f o r ccw from source , −1 f o r cw , 0 f o r n e i t h e runsigned i n t numInteract ions ; // number o f i n t e r a c t i o n s

void i n i t i a l i z e ( ) ;pub l i c :

Photon ( ) ; // d e f a u l t s are 0 or randomPhoton ( double f requency ) ; // s e t the f requencyPhoton ( double ∗ o r i g i n , double ∗ v e l o c i t y ) ; // s e t the o r i g i n

// s e t the o r i g i n and the f requencyPhoton ( double ∗ o r i g i n , double ∗ v e l o c i t y , double f requency ) ;

// s e t everyth ing

54

Photon ( double ∗ o r i g i n , double ∗ v e l o c i t y , double frequency ,double o r i e n t a t i o n , double phase , i n t c i r c u l a r P o l a r i z a t i o n ) ;

Photon ( Point o r i g i n , Point v e l o c i t y , double frequency , double o r i e n t a t i o ndouble phase , i n t c i r c u l a r P o l a r i z a t i o n ) ; // s e t everyth ing

Photon ( const Photon & photon ) {∗ t h i s = photon ; } ; // copy photon˜Photon ( ) {} ;Point getLocat ion ( ) const { re turn l o c a t i o n ; } ; // get the cur rent l o c a t i o nPoint ge tOr ig in ( ) const { re turn o r i g i n ; } ; // get the o r i g i n a l l o c a t i o nPoint g e tVe l o c i t y ( ) const { re turn v e l o c i t y ; } ; // get the v e l o c i t ys t a t i c double getC ( ) { re turn GSL CONST MKSA SPEED OF LIGHT ; } ;s t a t i c double getH ( ) { re turn GSL CONST MKSA PLANCKS CONSTANT H; } ;double getFrequency ( ) const { re turn f requency ; } ;double getWavelength ( ) const { re turn getC ( ) / f requency ; } ; // l=c/ fdouble getEnergy ( ) const { re turn getH ( ) ∗ f r equency ; } ; // E=hfdouble ge tOr i en ta t i on ( ) const ;double getPhase ( ) const { re turn phase ; } ;i n t g e t C i r c u l a r P o l a r i z a t i o n ( ) const { re turn c i r c u l a r P o l a r i z a t i o n ; } ;bool isCCW( ) const { re turn c i r c u l a r P o l a r i z a t i o n == 1;}bool isCW( ) const { re turn c i r c u l a r P o l a r i z a t i o n == −1;}bool i s L i n e a r ( ) const { re turn c i r c u l a r P o l a r i z a t i o n == 0;}

// d i s t anc e between coord inate s , not t o t a l d i s t anc e t r a v e l e ddouble getDistanceFromOrigin ( ) const ;unsigned i n t getNumInteract ions ( ) const { re turn numInteract ions ; } ;void s e tLoca t i on ( i n t i , double n ) ;void s e t O r i g i n ( i n t i , double n ) ;void s e t V e l o c i t y ( i n t i , double n ) ;void setFrequency ( double f requency )

{ i f ( f requency >= 0) th i s−>f r equency = frequency ; } ;void setWavelength ( double wavelength )

{ i f ( wavelength > 0) f requency = getC ( ) / wavelength ; } ;void setEnergy ( double energy )

{ i f ( energy > 0) f requency = energy / getH ( ) ; } ;void s e t O r i e n t a t i o n ( double o r i e n t a t i o n ) ;void setPhase ( double phase ) ;i n t s e t C i r c u l a r P o l a r i z a t i o n ( i n t n)

{ i f (n >= −1 && n <= 1) c i r c u l a r P o l a r i z a t i o n = n ; } ;bool setCCW( ) { c i r c u l a r P o l a r i z a t i o n = 1 ;}bool setCW ( ) { c i r c u l a r P o l a r i z a t i o n = −1;}bool s e tL inea r ( ) { c i r c u l a r P o l a r i z a t i o n = 0 ;}void setNumInteract ions ( unsigned i n t n) {numInteract ions = n ; } ;double normal ize ( ) ;void increment ( ) {numInteract ions ++;};void advance ( double amount , bool isTime = true ) ;s t r i n g toS t r i ng ( ) const ;

55

void p r i n t ( ) const ;void operator=(const Photon & photon ) ;

} ;#e n d i f

56

Photon.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Photon Class∗ 1−6−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude <c s t d l i b>#inc lude <sstream>#inc lude ” Point . h”#inc lude ”Photon . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set everyth ing to 0 , v e l o c i t y along the x1 axis , and the∗ f r equency to 1 .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( ){

i n i t i a l i z e ( ) ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set the f requency .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( double f requency ){

i n i t i a l i z e ( ) ;setFrequency ( f requency ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set the coo rd ina t e s and o r i g i n to the g iven po int . Also∗ s e t the v e l o c i t y .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( double ∗ o r i g i n , double ∗ v e l o c i t y ){

i n i t i a l i z e ( ) ;f o r ( i n t i = 0 ; i < Point : : SIZE ; i++)

57

{s e tLoca t i on ( i , o r i g i n [ i ] ) ;s e t O r i g i n ( i , o r i g i n [ i ] ) ;s e t V e l o c i t y ( i , v e l o c i t y [ i ] ) ;

}}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set the coo rd ina t e s and o r i g i n to the g iven po int . Set∗ the v e l o c i t y and the f requency .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( double ∗ o r i g i n , double ∗ v e l o c i t y , double f requency ){

i n i t i a l i z e ( ) ;f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , o r i g i n [ i ] ) ;s e t O r i g i n ( i , o r i g i n [ i ] ) ;s e t V e l o c i t y ( i , v e l o c i t y [ i ] ) ;

}setFrequency ( f requency ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set the coo rd ina t e s and o r i g i n to the g iven po int . Set∗ the v e l o c i t y , frequency , o r i e n t a t i o n , phase , and c i r c u l a r∗ p o l a r i z a t i o n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( double ∗ o r i g i n , double ∗ v e l o c i t y , double frequency ,

double o r i e n t a t i o n , double phase , i n t c i r c u l a r P o l a r i z a t i o n ){

i n i t i a l i z e ( ) ;f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , o r i g i n [ i ] ) ;s e t O r i g i n ( i , o r i g i n [ i ] ) ;s e t V e l o c i t y ( i , v e l o c i t y [ i ] ) ;

}setFrequency ( f requency ) ;s e t O r i e n t a t i o n ( o r i e n t a t i o n ) ;setPhase ( phase ) ;s e t C i r c u l a r P o l a r i z a t i o n ( c i r c u l a r P o l a r i z a t i o n ) ;

58

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Photon∗ Set the coo rd ina t e s and o r i g i n to the g iven po int . Set∗ the v e l o c i t y , frequency , o r i e n t a t i o n , phase , and c i r c u l a r∗ p o l a r i z a t i o n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon : : Photon ( Point o r i g i n , Point v e l o c i t y , double frequency ,

double o r i e n t a t i o n , double phase , i n t c i r c u l a r P o l a r i z a t i o n ){

i n i t i a l i z e ( ) ;f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , o r i g i n . getCoordinate ( i ) ) ;s e t O r i g i n ( i , o r i g i n . getCoordinate ( i ) ) ;s e t V e l o c i t y ( i , v e l o c i t y . getCoordinate ( i ) ) ;

}setFrequency ( f requency ) ;s e t O r i e n t a t i o n ( o r i e n t a t i o n ) ;setPhase ( phase ) ;s e t C i r c u l a r P o l a r i z a t i o n ( c i r c u l a r P o l a r i z a t i o n ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Or i entat ion∗ Get the cur rent o r i e n t a t i o n . For c i r c u l a r p o l a r i z a t i o n∗ the o r i e n a t i o n v a r i a b l e need not change , but the phase∗ must a l s o be cons ide r ed .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Photon : : g e tOr i en ta t i on ( ) const{

double cu r r en tOr i en ta t i on = o r i e n t a t i o n + c i r c u l a r P o l a r i z a t i o n ∗ phase ;i f ( cu r r en tOr i en ta t i on >= 360){

cu r r en tOr i en ta t i on −= 360 ;}e l s e i f ( cu r r en tOr i en ta t i on < 0){

cu r r en tOr i en ta t i on += 360 ;}re turn cur r en tOr i en ta t i on ;

} ;

59

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Distance From Orig in∗ Calcu la te the d i s t ance between the cur rent l o c a t i o n and∗ the o r i g i n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Photon : : getDistanceFromOrigin ( ) const{

re turn l o c a t i o n . ge tDi s tance ( o r i g i n ) ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Locat ion∗ Set a s p e c i f i c coo rd ina te o f the l o c a t i o n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : s e tLoca t i on ( i n t i , double n){

i f ( i >= 0 && i < Point : : SIZE )l o c a t i o n . se tCoord inate ( i , n ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Or ig in∗ Set a s p e c i f i c coo rd ina te o f the o r i g i n .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : s e t O r i g i n ( i n t i , double n){

i f ( i >= 0 && i < Point : : SIZE )o r i g i n . s e tCoord inate ( i , n ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Ve loc i ty∗ Set a s p e c i f i c coo rd ina te o f the v e l o c i t y .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : s e t V e l o c i t y ( i n t i , double n){

i f ( i >= 0 && i < Point : : SIZE )v e l o c i t y . s e tCoord inate ( i , n ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Or i entat i on∗ Set the o r i e n t a t i o n o f the E f i e l d o s c i l l a t i o n to some∗ ang le between 0 and 360 degree s .

60

∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : s e t O r i e n t a t i o n ( double o r i e n t a t i o n ){

whi le ( o r i e n t a t i o n < 0){

o r i e n t a t i o n += 360 ;}whi le ( o r i e n t a t i o n >= 360){

o r i e n t a t i o n −= 360 ;}th i s−>o r i e n t a t i o n = o r i e n t a t i o n ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Phase∗ Set the phase between the E and B f i e l d o s c i l l a t i o n a to∗ some ang le between 0 and 360 degree s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : setPhase ( double phase ){

whi le ( phase < 0){

phase += 360 ;}whi le ( phase >= 360){

phase −= 360 ;}th i s−>phase = phase ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ I n i t i a l i z e∗ Set d e f a u l t va lue s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : i n i t i a l i z e ( ){

f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , 0 ) ;s e t O r i g i n ( i , 0 ) ;s e t V e l o c i t y ( i , 0 ) ;

}

61

s e t V e l o c i t y (0 , 1 ) ;setFrequency ( 1 . 0 ) ;s e t O r i e n t a t i o n ( 0 ) ;setPhase ( 0 ) ;s e t C i r c u l a r P o l a r i z a t i o n ( 0 ) ;setNumInteract ions ( 0 ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Normalize∗ Return the n o r m a i l i z a t i o n constant f o r the r e l a t i v e∗ va lue s o f the components o f the v e l o c i t y such that the∗ magnitude would be the speed o f l i g h t .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Photon : : normal ize ( ){

i n t square = 0 ; // the sum of each component squaredf o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

square += pow( v e l o c i t y [ i ] , 2 ) ;}i f ( square == 0) // t h i s i s a problem , no d i r e c t i o n i s s p e c i f i e d{

s e t V e l o c i t y (0 , 1 . 0 ) ;square += 1 . 0 ;

}re turn getC ( ) / s q r t ( square ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Advance∗ Change the cur rent coo rd ina t e s o f the photon by advancing∗ along the d i r e c t i o n o f the v e l o c i t y by the amount , which∗ i s time in seconds by d e f a u l t ( but may a l s o be the∗ d i s t anc e in meters ) assuming the the photon t r a v e l s∗ with v e l o c i t y c . Adjust the phase .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : advance ( double amount , bool isTime ){

double time ;i f ( isTime ) // they gave us time to t r a v e l{

time = amount ;}

62

e l s e // they gave us d i s t anc e to t r a v e l{

time = amount / Photon : : getC ( ) ;}double normal = normal ize ( ) ; // get the constant o f norma l i za t i onf o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , ge tLocat ion ( ) [ i ] + ge tVe l o c i t y ( ) [ i ] ∗ normal ∗ time ) ;}double pe r i od s = frequency ∗ time ; // the number o f pe r i od s that went by// only the decimal part w i l l a f f e c t the phasedouble phaseChange = 360 ∗ ( pe r i od s − ( long ) pe r i od s ) ;phase += phaseChange ;i f ( phase > 360){

phase −= 360 ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ To St r ing∗ Convert to a s t r i n g .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/s t r i n g Photon : : t oS t r i ng ( ) const{

s t r i ng s t r eam stream ;stream << ”(” << ( getLocat ion ( ) . getCoordinate ( 0 ) ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

stream << ” ,” << getLocat ion ( ) . getCoordinate ( i ) ;}stream << ”) , [ ” << getOr ig in ( ) . getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

stream << ” ,” << getOr ig in ( ) . getCoordinate ( i ) ;}stream << ” ] , <” << ge tVe l o c i t y ( ) . getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

stream << ” ,” << ge tVe l o c i t y ( ) . getCoordinate ( i ) ;}stream << ”>, ” << f r equency << ” Hz , ” << o r i e n t a t i o n << ” , ”<< phase << ” , #” << numInteract ions ;

r e turn stream . s t r ( ) ;

63

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Print∗ Output a l l o f the va lue s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : p r i n t ( ) const{

cout << ”(” << getLocat ion ( ) . getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

cout << ” ,” << getLocat ion ( ) . getCoordinate ( i ) ;}cout << ”) , [ ” << getOr ig in ( ) . getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

cout << ” ,” << getOr ig in ( ) . getCoordinate ( i ) ;}cout << ” ] , <” << ge tVe l o c i t y ( ) . getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < Point : : SIZE ; i++){

cout << ” ,” << ge tVe l o c i t y ( ) . getCoordinate ( i ) ;}cout << ”>, ” << f r equency << ” Hz , ” << o r i e n t a t i o n << ” , ”<< phase << ” , #” << numInteract ions << endl ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Equals∗ Copy the g iven photon .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Photon : : operator=(const Photon & photon ){

f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

s e tLoca t i on ( i , photon . getLocat ion ( ) [ i ] ) ;s e t O r i g i n ( i , photon . ge tOr ig in ( ) [ i ] ) ;s e t V e l o c i t y ( i , photon . g e tVe l o c i t y ( ) [ i ] ) ;

}setFrequency ( photon . getFrequency ( ) ) ;s e t O r i e n t a t i o n ( photon . ge tOr i en ta t i on ( ) ) ;setPhase ( photon . getPhase ( ) ) ;setNumInteract ions ( photon . getNumInteract ions ( ) ) ;s e t C i r c u l a r P o l a r i z a t i o n ( photon . g e t C i r c u l a r P o l a r i z a t i o n ( ) ) ;

64

}

65

PiApproximation.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Pi Approximation∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude ” Source . h”#inc lude ” Detector . h”#inc lude ”Photon . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Main∗ For t e s t i n g purposes . Should g ive an answer about equal∗ to p i .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/i n t main ( ){

long n = 1000 ;double d0 [ 3 ] = {1000 , 0 , 0} ;double s0 [ 3 ] = {0 , 0 , 0} ;double a = atan2 (1 , 1000) ∗ 180 / M PI ;Detector d( d0 , 0 , 180 , 90 , 270 , 1 . 0 ) ;Source s ( s0 , (90 − a ) , (90 + a ) , 360 − a , a ) ;f o r ( i n t i = 0 ; i < 4 ∗ n ; i++){

cout << i << endl ;Photon p = s . emit ( ) ;i f (d . detec ted (p , 1001 , f a l s e ) ){

d . setNumDetected (d . getNumDetected ( ) + 1 .0 / n ) ;}

}cout << d . getNumDetected ( ) << endl ;r e turn 0 ;

}

66

Point.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Point Header∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f POINT H#d e f i n e POINT H

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Point Class∗ Cartes ian space po int .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Point{

pub l i c :s t a t i c const i n t SIZE = 3 ; // dimensions o f space

p r i v a t e :double coord inate [ SIZE ] ;

pub l i c :Point ( ) ;Point ( double ∗ c ) ;Point ( const Point & p ) ;double getCoordinate ( i n t i ) const { re turn ( i >= 0 && i < SIZE ) ?

coord inate [ i ] : 0 ; } ; // get coord inate va luevoid setCoord inate ( i n t i , double n) { i f ( i >= 0 && i < SIZE )

coord inate [ i ] = n ; } ; // s e t coord inate valuedouble getDi s tance ( const Point & p) const ;double ca l cu l a t eAng l e ( const Point & p1 , const Point & p2 ) const ;void p r i n t ( ) const ;double operator [ ] ( i n t i ) { re turn coord inate [ i ] ; } ;void operator=(const Point & p ) ;

} ;#e n d i f

67

Point.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Point Class∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude ” Point . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Point∗ Set every coord inate to 0 .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Point : : Point ( ){

f o r ( i n t i = 0 ; i < SIZE ; i++){

se tCoord inate ( i , 0 ) ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Point∗ Set every coord inate to match array c .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Point : : Point ( double ∗ c ){

f o r ( i n t i = 0 ; i < SIZE ; i++){

se tCoord inate ( i , c [ i ] ) ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Point∗ Copy po int p .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Point : : Point ( const Point & p){

f o r ( i n t i = 0 ; i < SIZE ; i++){

68

se tCoord inate ( i , p . getCoordinate ( i ) ) ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Distance∗ Get the d i s t anc e between the two po in t s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Point : : ge tDi s tance ( const Point & p) const{

double d = 0 ;f o r ( i n t i = 0 ; i < SIZE ; i++){

d += pow ( ( th i s−>getCoordinate ( i ) − p . getCoordinate ( i ) ) , 2 ) ;}re turn s q r t (d ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Calcu la te Angle∗ Get the ang le in degree s made by the two given po in t s∗ with t h i s po int as the ver tex . Use the law o f c o s i n e s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Point : : c a l cu l a t eAng l e ( const Point & p1 , const Point & p2 ) const{

double a = p1 . getDi s tance ( p2 ) ;double b = th i s−>getDi s tance ( p1 ) ;double c = th i s−>getDi s tance ( p2 ) ;i f ( a == 0 | | b == 0 | | c == 0){

re turn 0 ;}double r a t i o = (pow(b , 2) + pow( c , 2) − pow( a , 2 ) ) / (2 ∗ b ∗ c ) ;i f ( r a t i o > 1){

r a t i o = 1 . 0 ;}e l s e i f ( r a t i o < −1){

r a t i o = −1.0;}re turn acos ( r a t i o ) ∗ 180 / M PI ;

}

69

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Print∗ Print the va lue s o f the coo rd ina t e s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Point : : p r i n t ( ) const{

cout << ”(” << getCoordinate ( 0 ) ;f o r ( i n t i = 1 ; i < SIZE ; i++){

cout << ” ,” << getCoordinate ( i ) ;}cout << ” ) ” ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Equals∗ Copy po int p .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Point : : operator=(const Point & p){

f o r ( i n t i = 0 ; i < SIZE ; i++){

se tCoord inate ( i , p . getCoordinate ( i ) ) ;}

}

70

RandomSingleton.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Point Header∗ 2−12−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f RANDOM SINGLETON H#d e f i n e RANDOM SINGLETON H#inc lude <g s l / g s l r n g . h>us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Random S ing l e ton Class∗ Gives everyone r e l i a b l e random numbers .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s RandomSingleton{

p r i v a t e :g s l r n g ∗ rng ;RandomSingleton ( ) ;

pub l i c :˜RandomSingleton ( ) ;s t a t i c RandomSingleton & ge t In s tance ( ) { s t a t i c RandomSingleton in s t ance ;

r e turn in s t anc e ; } ;double rand ( ) ;double rand ( double max ) ;double rand ( double min , double max ) ;void seed ( unsigned long i n t seed ) ;

} ;#e n d i f

71

RandomSingleton.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Point Class∗ 2−12−2015∗ gs l rng mt19937 was s e l e c t e d over the other g s l rngs∗ becuase o f the long per iod f o r a g iven seed , and the∗ speed with which a new number can be acqu i red . Both o f∗ the se c h a r a c t e r i s t i c s are e s s e n t i a l in a Monte Carlo∗ s imu la t i on .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <sys / time . h>#inc lude <g s l / g s l r n g . h>#inc lude ”RandomSingleton . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Constructor∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/RandomSingleton : : RandomSingleton ( ){

rng = g s l r n g a l l o c ( gs l rng mt19937 ) ;t imeva l tv ;gett imeofday (&tv , NULL) ;unsigned long i n t seed = ( tv . t v s e c ∗ 1000) + ( tv . tv u s e c / 1000) ;g s l r n g s e t ( rng , seed ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Destructor∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/RandomSingleton : : ˜ RandomSingleton ( ){

g s l r n g f r e e ( rng ) ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Rand∗ Generate random number [ 0 , 1 ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double RandomSingleton : : rand ( ){

re turn g s l r n g u n i f o r m ( rng ) ;

72

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Rand∗ Generate random number [ 0 , max ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double RandomSingleton : : rand ( double max){

re turn max ∗ g s l r n g u n i f o r m ( rng ) ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Rand∗ Generate random number [ min , max ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double RandomSingleton : : rand ( double min , double max){

re turn (max − min ) ∗ g s l r n g u n i f o r m ( rng ) + min ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Seed∗ Seed us ing the g iven number .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void RandomSingleton : : seed ( unsigned long i n t seed ){

rng = g s l r n g a l l o c ( gs l rng mt19937 ) ;g s l r n g s e t ( rng , seed ) ;

}

73

Rayleigh.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Rayle igh Header∗ 2−5−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f RAYLEIGH H#d e f i n e RAYLEIGH H

#inc lude ”Medium . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Rayle igh Class∗ This c l a s s s imu la t e s a medium f o r photons to pass∗ through . The photons undergo Rayle igh s c a t t e r i n g .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Rayle igh : pub l i c Medium{

p r i v a t e :double d i s t r i b u t e ( double ang le ) const ;

pub l i c :Rayle igh ( ) : Medium ( ) {} ;Rayle igh ( Point po int ) : Medium( po int ) {} ;Rayle igh ( double ∗ coord inate ) : Medium( coord inate ) {} ;Rayle igh ( double rad iu s ) : Medium( rad iu s ) {} ;Rayle igh ( Point point , double rad iu s ) : Medium( point , r ad iu s ) {} ;Rayle igh ( double ∗ coord inate , double rad iu s ) : Medium( coord inate , r ad iu s )

{} ;Rayle igh ( const Medium & medium) : Medium(medium) {} ;v i r t u a l void s c a t t e r ( Photon &photon ) ;

} ;#e n d i f

74

Rayleigh.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Rayle igh Class∗ 2−5−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude ” Rayle igh . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ D i s t r i b u t e∗ Given an ang le [ 0 , PI ) , i f a random number [ 0 , 1 ) i s g r e a t e r than∗ 2∗ cos ( ang le )ˆ2 then r e d i s t r i b u t e the ang le∗ to match that exact func t i on . Then return the ang le .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double Rayle igh : : d i s t r i b u t e ( double ang le ) const{

// i f a random number [ 0 , 1 ) i s l e s s than 2∗ cos ( ang le )ˆ2 , r e d i s t r i b u t e ang lei f ( getRS ( ) . rand ( ) > 2 ∗ pow( cos ( ang le ) , 2 ) ){

i f ( ang le > M PI / 2 . 0 ){

ang le += 2 ∗ ( 3 . 0 ∗ M PI / 4 .0 − ang le ) ;}e l s e{

ang le −= 2 ∗ ( ang le − M PI / 4 . 0 ) ;}

}re turn ang le ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Sca t t e r∗ This i s the ba s i c func t i on to change the v e l o c i t y , and∗ p o s s i b l y the f requency o f a g iven photon . Should c a l l∗ increment on the photon .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Rayle igh : : s c a t t e r ( Photon &photon ){

i f ( isInMedium ( photon . getLocat ion ( ) ) )

75

{// we need the v e l o c i t y o f the photondouble vx = photon . g e tVe l o c i t y ( ) . getCoordinate ( 0 ) ;double vy = photon . g e tVe l o c i t y ( ) . getCoordinate ( 1 ) ;double vz = photon . g e tVe l o c i t y ( ) . getCoordinate ( 2 ) ;// ang le that t h i s event w i l l r o t a t e and s c a t t e r the photon// pe rpend i cu la r to the d i r e c t i o n o f t r ave l , measured ccw// from the z−a x i s from the po int o f view o f the source o f the photondouble phi = getRS ( ) . rand ( ) ∗ 2 ∗ M PI ; // 0−2PI

// r e l a t i v e ang ledouble alpha = photon . ge tOr i en ta t i on ( ) ∗ M PI / 180 − phi ;i f ( alpha < 0){

alpha += 2 ∗ M PI ;}

// theta w i l l e i t h e r be i s o t r o p i c or notbool i s o t r o p i c = getRS ( ) . rand ( ) < (−cos (2 ∗ alpha ) / 2 + . 5 ) ;

// take acos o f t h i s ang le as a s c a l a r [−1 , 1 ] to get thetadouble beta = getRS ( ) . rand ( ) ∗ M PI ;i f ( ! i s o t r o p i c ){

beta = d i s t r i b u t e ( beta ) ;photon . s e t O r i e n t a t i o n ( getRS ( ) . rand (0 , 3 6 0 ) ) ;

// t h i s l i n e becomes important in the ca s e s o f c i r c u l a r p o l a r i z a t i o nphoton . setPhase ( 0 ) ;

}double theta = acos (2 ∗ beta / M PI − 1 ) ; // 0−PI and not uniform// tak ing the acos i s nece s sa ry even in the i s o t r o p i c case , because// we are us ing s p h e r e i c a l c oo rd ina t e s and we want the d i s t r i b u t i o n// at the p l o e s to have the same dens i ty and the d i s t r i b u t i o n at// the equatordouble a = vx ; // w i l l be ro ta ted to become the new vxdouble b = vy ; // w i l l be ro ta ted to become the new vydouble c = vz ; // w i l l be ro ta ted to become the new vzdouble d = −vy ; // componenet o f a x i s in the x−y planedouble e = vx ; // componenet o f a x i s in the x−y planei f ( vx == 0 && vy == 0) // s p e c i a l case when v i s only in the z d i r e c t i o n{

d = vz / abs ( vz ) ;}s e tRotate r (d , e , 0 ) ; // s e t an a x i s in the x−y plane , pe rpend i cu l a r to vr o t a t e r . r o t a t e ( a , b , c , theta ∗ 180 / M PI ) ; // r o t a t e by theta degree ss e tRotate r ( vx , vy , vz ) ; // s e t v as the a x i s o f r o t a t i o nr o t a t e r . r o t a t e ( a , b , c , phi ∗ 180 / M PI ) ; // r o t a t e by phi degree s

76

photon . s e t V e l o c i t y (0 , a ) ; // new vxphoton . s e t V e l o c i t y (1 , b ) ; // new vyphoton . s e t V e l o c i t y (2 , c ) ; // new vz// number o f s c a t t e r i n g events f o r the photon should be incremented// by onephoton . increment ( ) ;

}}

77

SimulateAtmosphere.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Simulate Atmosphere∗ 3−6−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <s t d l i b . h>#inc lude <cmath>#inc lude <sys / time . h>#inc lude ” Va l idat ionS imulat i on . h”#inc lude ”Atmosphere . h”#inc lude ” V i s i b l eSou r c e . h”#inc lude ” Detector . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Main∗ For t e s t i n g purposes .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/i n t main ( i n t argc , char ∗argv [ ] ){

double r = 100000;double d = r ∗ s q r t ( 3 ) ;double ps [ 3 ] = {−d , 0 , 0} ;double pa [ 3 ] = {0 , 0 , 0} ;double pd [ 3 ] = {d , 0 , 0} ;V i s i b l eSou r c e vs ( ps , 60 . 0 , 120 .0 , 330 .0 , 3 0 . 0 ) ;Atmosphere atm( pa , r ) ;Detector de t e c t o r (pd , 60 . 0 , 120 .0 , 150 .0 , 210 .0 , r ) ;i n t num = 1000 ;s t r i n g hostname ( getenv (”HOSTNAME” ) ) ;i f ( argc > 1){

num = a t o i ( argv [ 1 ] ) ;}ofstream fout , f , p ;i f ( argc > 2){

s t r i n g name( argv [ 2 ] ) ;f out . open ( ( name + ”−” + hostname + ” . out ” ) . c s t r ( ) ) ;f . open ( ( name + ”−” + hostname + ”− f . out ” ) . c s t r ( ) ) ;p . open ( ( name + ”−” + hostname + ”−p . out ” ) . c s t r ( ) ) ;

78

}e l s e{

f out . open ( ( hostname + ” . out ” ) . c s t r ( ) ) ;f . open ( ( hostname + ”− f . out ” ) . c s t r ( ) ) ;p . open ( ( hostname + ”−p . out ” ) . c s t r ( ) ) ;

}Val idat ionS imula t i on sim ( vs , detec tor , atm , num ) ;t imeva l tv ;gett imeofday (&tv , NULL) ;unsigned long i n t seed = ( tv . t v s e c ∗ 1000) + ( tv . tv u s e c / 1000) ;i n t o f f s e t = 0 ;f o r ( i n t i = 0 ; i < hostname . s i z e ( ) ; i++){

o f f s e t += pow(10 , i ) ∗ hostname [ i ] ;}sim . getRS ( ) . seed ( seed + o f f s e t ) ;sim . run ( fout ) ;f << sim . ge tFrequenc i e s ( ) . t oS t r i ng ( ) ;p << sim . g e t P o l a r i z a t i o n s ( ) . t oS t r i ng ( ) ;f out . c l o s e ( ) ;f . c l o s e ( ) ;p . c l o s e ( ) ;r e turn 0 ;

}

79

Simulation.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Simulat ion Header∗ 1−8−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f SIMULATION H#d e f i n e SIMULATION H

#inc lude <fstream>#inc lude ” Source . h”#inc lude ” Detector . h”#inc lude ”Photon . h”#inc lude ”Medium . h”#inc lude ”RandomSingleton . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Simulat ion Class∗ This c l a s s runs a Monte Carlo s imu la t i on . The source∗ be pointed at or in the medium .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s S imulat ion{

protec ted :Source ∗ source ; // Source o f photonsDetector ∗ de t e c t o r ; // Detector o f photonsMedium ∗ medium ;unsigned long i n t numIterat ions ;s t r i n g header ;v i r t u a l s t r i n g format ( const Photon & photon ) ;

pub l i c :S imulat ion ( Source & source , Detector & detector , Medium & medium ,

unsigned long i n t numIterat ions , s t r i n g header = ””){ th i s−>source = &source ; th i s−>de t e c t o r = &det e c t o r ;

th i s−>medium = &medium ; th i s−>numIterat ions = numIterat ions ;th i s−>header = header ; } ;

Source & getSource ( ) { re turn ∗ source ; } ;Detector & getDetector ( ) { re turn ∗ de t e c t o r ; } ;Medium & getMedium ( ) { re turn ∗medium ; } ;unsigned long i n t getNumIterat ions ( ) { re turn numIterat ions ; } ;s t a t i c RandomSingleton & getRS ( )

{ re turn RandomSingleton : : g e t In s tance ( ) ; } ;void setNumIterat ions ( unsigned long i n t numIterat ions )

80

{ th i s−>numIterat ions = numIterat ions ; } ;void run ( ofstream & fout ) ;

} ;#e n d i f

81

Simulation.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Simulat ion Class∗ 2−27−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude <sstream>#inc lude ” Simulat ion . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Format∗ Format the data f o r gnuplot . In t h i s scope you have∗ a c c e s s to the photon be f o r e i t was detected , the∗ detector , medium , and source .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/s t r i n g Simulat ion : : format ( const Photon & photon ){

re turn photon . t oS t r i ng ( ) ;}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Run∗ Run the s imu la t i on .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void Simulat ion : : run ( ofstream & fout ){

Photon photon ;double d i s t anc e ;double f r e e D i s t a n c e ;long double percent = numIterat ions / 9 9 . 0 ;i n t x = −1;f out << header << endl ;f o r ( i n t i = 0 ; i < numIterat ions ; i++){

photon = getSource ( ) . emit ( ) ; // new photond i s t anc e = photon . getLocat ion ( ) . ge tDi s tance (

getMedium ( ) . getLocat ion ( ) ) + . 0 1 ;whi l e ( ! getMedium ( ) . isInMedium ( photon . getLocat ion ( ) ) &&

photon . getLocat ion ( ) . ge tDi s tance (getMedium ( ) . getLocat ion ( ) ) < d i s t anc e )

82

{// get to the edge fo the medium

d i s t anc e = photon . getLocat ion ( ) . ge tDi s tance (getMedium ( ) . getLocat ion ( ) ) ;

photon . advance (d i s t anc e − getMedium ( ) . getRadius ( ) ∗ . 9999 , f a l s e ) ;

}whi le ( getMedium ( ) . isInMedium ( photon . getLocat ion ( ) ) ){

// whi l e we are in the medium// get f r e e d i s t ance

f r e e D i s t a n c e = getMedium ( ) . getFreeDis tance ( photon ) ;// photon detec ted

i f ( ge tDetector ( ) . de tec ted ( photon , f r e eD i s tance , f a l s e ) ){

f out << format ( photon ) << endl ; // format and output the r e s u l t// end the whi l e loop

photon . advance ( getMedium ( ) . getRadius ( ) ∗ 2 , f a l s e ) ;}e l s e // photon not detec ted{

photon . advance ( f r e eD i s tance , f a l s e ) ; // advance photon// s t i l l in medium

i f ( getMedium ( ) . isInMedium ( photon . getLocat ion ( ) ) ){

getMedium ( ) . s c a t t e r ( photon ) ; // s c a t t e r photon}e l s e i f ( ge tDetector ( ) . de tec ted ( photon , photon . getLocat ion ( )

. ge tDi s tance ( getDetector ( ) . getLocat ion ( ) ) , f a l s e ) ){

// check f o r the case that the de t e c t o r// i s ou t s i d e the medium but that the// photon i s headed s t r a i g h t towards i t// format and output the r e s u l t

f out << format ( photon ) << endl ;}

}}i f ( ( double ) i / percent > x ) // output s t a t u s{

whi le ( ( double ) i / percent > x ){

x++;}

83

cout << x << ”% complete \n ” ;}

}i f ( x != 100){

cout << ”100% complete \n ” ;}

}

84

SolidAngle.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ S o l i d Angle Header∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f SOLID ANGLE H#d e f i n e SOLID ANGLE H

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ S o l i d Angle Class∗ An angle with an upper and lower range . Everything i s in∗ degree s . I f i sFu l lAng l e i s s e t to f a l s e then that means∗ that the ranges are a l l bound [ 0 , 1 8 0 ) . I f min i s g r e a t e r∗ numer i ca l ly than max then the v a l i d range wraps around∗ from min to max .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s So l idAngle{

p r i v a t e :s t a t i c const double FULL = 3 6 0 . 0 ;s t a t i c const double HALF = 1 8 0 . 0 ;bool i sFu l lAng l e ;double min ;double max ;double reduce ( double n) const ;

pub l i c :So l idAngle ( )

{ i sFu l lAng l e = true ; setMin ( 0 ) ; setMax ( .999999 ∗ FULL ) ; } ;So l idAngle ( bool i sFu l lAng l e )

{ th i s−>i sFu l lAng l e = i sFu l lAng l e ; setMin ( 0 ) ;setMax ( ( i sFu l lAng l e ) ? .999999 ∗ FULL : .999999 ∗ HALF) ; } ;

So l idAngle ( double min , double max){ i sFu l lAng l e = true ; setMin ( min ) ; setMax (max ) ; } ;

So l idAngle ( double min , double max , bool i sFu l lAng l e ){ th i s−>i sFu l lAng l e = i sFu l lAng l e ; setMin ( min ) ; setMax (max ) ; } ;

So l idAngle ( const So l idAngle & so l idAng l e ){ i sFu l lAng l e = so l i dAng l e . i sFu l lAng l e ;setMin ( so l i dAng l e . getMin ( ) ) ; setMax ( so l i dAng l e . getMax ( ) ) ; } ;

double getMin ( ) const { re turn min ; } ;double getMax ( ) const { re turn max ; } ;double getRange ( ) const ;void setMin ( double n ) ;

85

void setMax ( double n ) ;bool isInRange ( double n) const ;void p r i n t ( ) const ;

} ;#e n d i f

86

SolidAngle.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ S o l i c Angle Class∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude ” Sol idAngle . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Reduce∗ Put the ang le in the range [0−360).∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double So l idAngle : : reduce ( double n) const{

whi le (n < 0){

n += FULL;}whi le (n >= FULL){

n −= FULL;}re turn n ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Range∗ Get the magnitude o f the v a l i d range .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/double So l idAngle : : getRange ( ) const{

i f ( min <= max){

re turn max − min ;}e l s e{

re turn ( i sFu l lAng l e ) ? (FULL − min + max) : (HALF − min + max ) ;}

}

87

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Min∗ Set minimum angle ( does not have to be l e s s than max∗ ang le ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void So l idAngle : : setMin ( double n){

n = reduce (n ) ;i f ( i sFu l lAng l e | | n < HALF){

min = n ;}e l s e{

min = FULL − n ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Set Max∗ Set maximum angle ( does not have to be more than min∗ ang le ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void So l idAngle : : setMax ( double n){

n = reduce (n ) ;i f ( i sFu l lAng l e | | n < HALF){

max = n ;}e l s e{

max = FULL − n ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ I s In Range∗ Return true i s the g iven ang le i s with in the s o l i d ang le .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/bool So l idAngle : : i s InRange ( double n) const{

88

n = reduce (n ) ;i f ( min <= max){

re turn n >= min && n <= max ;}e l s e i f ( ! i sFu l lAng l e && n >= HALF){

n = FULL − n ;}re turn ! ( n > min && n < max ) ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Print∗ Print the va lue s o f the coo rd ina t e s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/void So l idAngle : : p r i n t ( ) const{

cout << ” [” << min << ” ,” << max << ” ] ” ;}

89

Source.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Source Header∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f SOURCE H#d e f i n e SOURCE H

#inc lude ”Photon . h”#inc lude ” Point . h”#inc lude ” Sol idAngle . h”#inc lude ”RandomSingleton . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Source Class∗ This c l a s s s imu la t e s a source o f l i g h t .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Source{

p r i v a t e :Point l o c a t i o n ;So l idAngle theta ; //0 to p iSo l idAngle phi ; //0 to 2 p i

pub l i c :Source ( ) : l o c a t i o n ( ) , theta ( f a l s e ) , phi ( t rue ) {} ;Source ( double ∗ coord inate , double thetaMin , double thetaMax ,

double phiMin , double phiMax ) ;Source ( const Source & source ) : l o c a t i o n ( source . getLocat ion ( ) ) ,

theta ( source . getTheta ( ) ) , phi ( source . getPhi ( ) ) {} ;Point getLocat ion ( ) const { re turn l o c a t i o n ; } ; // get the l o c a t i o nSol idAngle getTheta ( ) const { re turn theta ; } ; // get the v e r t i c a l ang leSo l idAngle getPhi ( ) const { re turn phi ; } ; // get the h o r i z o n t a l ang lePoint g e tVe l o c i t y ( ) ;s t a t i c RandomSingleton & getRS ( )

{ re turn RandomSingleton : : g e t In s tance ( ) ; } ;void s e tLoca t i on ( i n t min , double max) { theta . setMin ( min ) ;

theta . setMax (max ) ; } ;void setTheta ( double min , double max) { theta . setMin ( min ) ;

theta . setMax (max ) ; } ;void setPhi ( double min , double max) {phi . setMin ( min ) ; phi . setMax (max ) ; } ;v i r t u a l Photon emit ( ) ;

} ;

90

#e n d i f

91

Source.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Source Class∗ 1−21−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude ” Source . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Source∗ I n i t i a l i z e everyth ing . Phi must be a f u l l angle , and∗ theta a h a l f ang le .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Source : : Source ( double ∗ coord inate , double thetaMin , double thetaMax ,

double phiMin , double phiMax ) : theta ( thetaMin , thetaMax , f a l s e ) ,phi ( phiMin , phiMax , t rue )

{f o r ( i n t i = 0 ; i < Point : : SIZE ; i++){

l o c a t i o n . se tCoord inate ( i , coo rd inate [ i ] ) ;}

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Get Ve loc i ty∗ Generate the v e l o c i t y o f the g iven photon .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Point Source : : g e tVe l o c i t y ( ){

Point v e l o c i t y ;double t , p ;i f ( theta . getMin ( ) <= theta . getMax ( ) ){

t = theta . getMin ( ) + theta . getRange ( ) ∗ getRS ( ) . rand ( ) ;}e l s e{

t = theta . getMin ( ) − theta . getRange ( ) ∗ getRS ( ) . rand ( ) ;}p = phi . getMin ( ) + phi . getRange ( ) ∗ getRS ( ) . rand ( ) ;

92

v e l o c i t y . s e tCoord inate (0 , cos (p ∗ M PI / 180) ∗ s i n ( t ∗ M PI / 1 8 0 ) ) ;v e l o c i t y . s e tCoord inate (1 , s i n (p ∗ M PI / 180) ∗ s i n ( t ∗ M PI / 1 8 0 ) ) ;v e l o c i t y . s e tCoord inate (2 , cos ( t ∗ M PI / 1 8 0 ) ) ;r e turn v e l o c i t y ;

}

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Emit∗ Generate a photon with a l l o f the r i g h t c h a r a c t e r i s t i c s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon Source : : emit ( ){

Photon photon ( getLocat ion ( ) , g e tVe l o c i t y ( ) , 100 , getRS ( ) . rand (360) ,getRS ( ) . rand (360) , getRS ( ) . rand ( 3 6 0 ) ) ;

r e turn photon ;}

93

ValidationSimulation.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Val idat i on Simulat ion Header∗ 3−18−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f VALIDATION SIMULATION H#d e f i n e VALIDATION SIMULATION H

#inc lude ” Simulat ion . h”#inc lude ”Histogram . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Val idat i on Simulat ion Class∗ This c l a s s runs a Monte Carlo s imu la t i on . I t v a l i d a t e s∗ the model f o r s imple r a y l e i g h s c a t t e r i n g in∗ the atmosphere .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s Va l idat ionS imulat i on : pub l i c S imulat ion{

protec ted :Histogram f r e q u e n c i e s ;Histogram p o l a r i z a t i o n s ;v i r t u a l s t r i n g format ( const Photon & photon ) ;

pub l i c :Va l idat ionS imula t i on ( Source & source , Detector & detector ,

Medium & medium , unsigned long i n t numIterat ions ) :S imulat ion ( source , detec tor , medium , numIterat ions ) ,f r e q u e n c i e s (1000 , 3 .89 e11 , 400 .0 e12 ) , p o l a r i z a t i o n s (360 , 1 , 0){header = ” Source−ang le Frequency” +” Relat ive−P o l a r i z a t i o n Z−approach Z−l i n e a r−p o l a r i z a t i o n ” ; } ;

Histogram getFrequenc i e s ( ) const { re turn f r e q u e n c i e s ; } ;Histogram g e t P o l a r i z a t i o n s ( ) const { re turn p o l a r i z a t i o n s ; } ;

} ;#e n d i f

94

ValidationSimulation.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ Val idat i on Simulat ion Class∗ 3−18−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude <iostream>#inc lude <cmath>#inc lude <sstream>#inc lude ” Va l idat ionS imulat i on . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Format∗ Format the data f o r gnuplot . Should output ” Source−ang le∗ Frequency Relat ive−P o l a r i z a t i o n Z−approach∗ Z−l i n e a r−p o l a r i z a t i o n ”∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/s t r i n g Va l idat ionS imula t i on : : format ( const Photon & photon ){

s t r i ng s t r eam data ;Point p = photon . getLocat ion ( ) ; // photonPoint c = getDetector ( ) . getLastContact ( ) ; // contactPoint s = getSource ( ) . getLocat ion ( ) ; // sourcedouble angleFromSource = c . ca l cu l a t eAng l e (p , s ) ; // ang le pcsdouble angleFromZ ;i f ( angleFromSource < 0 . 1 ) // case o f a l l unscat te red photons{

angleFromZ = 0 ;}e l s e{

// from s to cdouble sc [ 3 ] = {c . getCoordinate (0 ) − s . getCoordinate ( 0 ) ,

c . getCoordinate (1 ) − s . getCoordinate ( 1 ) ,c . getCoordinate (2 ) − s . getCoordinate ( 2 ) } ;

Rotation r = getMedium ( ) . getRotater ( ) ;// s e t a x i s o f r o t a t i o n to z−a x i sr . s e tAx i s (0 , 0 ) ;r . s e tAx i s (1 , 0 ) ;r . s e tAx i s (2 , 1 ) ;

// from s to pdouble sp [ 3 ] = {p . getCoordinate (0 ) − s . getCoordinate ( 0 ) ,

95

p . getCoordinate (1 ) − s . getCoordinate ( 1 ) ,p . getCoordinate (2 ) − s . getCoordinate ( 2 ) } ;

// f o r c a l c u l a t i n g the ang l e s to r o t a t e sp such that sc would be// on the x−a x i s

double d = s q r t (pow( sc [ 0 ] , 2) + pow( sc [ 1 ] , 2 ) ) ;// z−a x i s r o t a t i o n

r . r o t a t e ( sp [ 0 ] , sp [ 1 ] , sp [ 2 ] , −atan2 ( sc [ 1 ] , s c [ 0 ] ) ∗ 180 / M PI ) ;// s e t a x i s o f r o t a t i o n to y−a x i sr . s e tAx i s (0 , 0 ) ;r . s e tAx i s (1 , 1 ) ;r . s e tAx i s (2 , 0 ) ;

// y−a x i s r o t a t i o nr . r o t a t e ( sp [ 0 ] , sp [ 1 ] , sp [ 2 ] , atan2 ( sc [ 2 ] , d ) ∗ 180 / M PI ) ;angleFromZ = ( atan2(−sp [ 1 ] , sp [ 2 ] ) ∗ 180 / M PI + 1 8 0 ) ;

}// o r i e n t a t i o n − ang le o f i n c i d e n c e from z−a x i sdouble r e l a t i v e P o l a r i z a t i o n = photon . ge tOr i en ta t i on ( ) − angleFromZ ;i f ( r e l a t i v e P o l a r i z a t i o n < 0){

r e l a t i v e P o l a r i z a t i o n += 360 ;}i f ( angleFromSource >= 0 . 1 ){

f r e q u e n c i e s << photon . getFrequency ( ) ;}i f ( angleFromSource >= 45 && angleFromSource < 46){

p o l a r i z a t i o n s << r e l a t i v e P o l a r i z a t i o n ;}data << angleFromSource << ” ” << photon . getFrequency ( ) << ” ”<< r e l a t i v e P o l a r i z a t i o n << ” ” << angleFromZ << ” ”

<< photon . g e tOr i en ta t i on ( ) ;r e turn data . s t r ( ) ;

}

96

VisibleSource.h

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ V i s i b l e Source Header∗ 3−2−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#i f n d e f VISIBLE SOURCE H#d e f i n e VISIBLE SOURCE H

#inc lude ” Source . h”

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ V i s i b l e Source Class∗ This c l a s s s imu la t e s a source o f v i s i b l e l i g h t . The∗ emitted photons are incoherent , have random ( l i n e a r )∗ p o l a r i z a t i o n , and a evenly d i s t r i b u t e d random frequency∗ [ 400 THz, 789 THz ) .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/c l a s s V i s i b l eSou r c e : pub l i c Source{

pub l i c :V i s i b l eSou r c e ( ) {} ;V i s i b l eSou r c e ( double ∗ coord inate , double thetaMin , double thetaMax ,

double phiMin , double phiMax ) : Source ( coord inate , thetaMin ,thetaMax , phiMin , phiMax ) {} ;

V i s i b l eSou r c e ( const Source & source ) : Source ( source ) {} ;v i r t u a l Photon emit ( ) ;

} ;#e n d i f

97

VisibleSource.cpp

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ James Nelson∗ V i s i b l e Source Class∗ 3−2−2015∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/#inc lude ” V i s i b l eSou r c e . h”us ing namespace std ;

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ Emit∗ Generate a photon with a l l o f the r i g h t c h a r a c t e r i s t i c s .∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/Photon V i s i b l eSou r c e : : emit ( ){

Photon photon ( getLocat ion ( ) , g e tVe l o c i t y ( ) , getRS ( ). rand (400 . 0 e12 , 789 .0 e12 ) , getRS ( ) . rand (360) ,

getRS ( ) . rand (360) , 0 ) ;r e turn photon ;

}

98