Introduction
For years, I have worked on development of user-driven applications. These are the programs in which only users decide about the general view of the forms and about the details of all the involved elements. Such applications are extremely valuable for all branches of science and engineering because in these areas, the requirements for the needed software changes all the time throughout the process of research. If it is impossible to formulate the requirements for programs at the beginning of their development, then designers have to produce applications which would work regardless of whatever users are going to do with them. The task uncertainty is a standard situation in science, but the same situation can happen in other areas which are very far from science and engineering. Years ago I demonstrated this type of application for Family Tree design; even a simple Calculator which didn’t change for decades and became much more convenient when users get full control over it.
Now I want to show a program for a course of Geometric Optics.
There is a program and there is a small book with the same title as this short article. The book is "Illustration for Geometric Optics" and consists of two parts. Thef first part describes the included examples from the point of Optics while the second part is about the programming of those examples. In this short article, I try to combine some figures from the book with the code examples. For figures in this article, their original numeration from the book is used.
I hope that the majority of readers remember the main items and questions which are discussed in the course of Geometric Optics. There are flat and curved mirrors; there are refraction, total internal reflection, and dispersion; there are lenses and image construction. All these items are discussed in the book while only some of them are mentioned in this article.
About the Movability of Elements
It is impossible to write about a program of the new type without mentioning its basis. I’ll try to give a very brief description because the program discussion cannot go on without mentioning the most important features of application.
The best place to read about the algorithm, its details, and the results of using movable objects is the "Introduction to User-Driven Applications" at https://sourceforge.net/projects/movegraph/files/. The book is accompanied by an application; all its code (in C#) is available.
All objects which appear in user-driven applications are movable and resizable. An object is moved by its inner points; press anywhere inside with the left button and move an object to the needed place. To rotate an object, the right button is used in the same easy way. Resizing is done by pressing any object border point with the left button.
Movability and resizability of any object are provided by its invisible cover which consists of cover nodes. Nodes of three different shapes are used in my algorithm. There are circles, rounded strips (a rectangle with additional semicircles at two opposite sides), and convex polygons.
Movability of all objects is extremely valuable for scientific, engineering, and any other programs. Throughout the following text I demonstrate some figures of different examples, but you have to keep in mind one thing. There are no sets of positions for these objects which I especially calculated in order to demonstrate some very interesting optical effects. I myself have used all these objects; I add them and delete; I move them, rotate, and resize. When I see the composition which can perfectly illustrate one or another statement in my book on Geometric Optics, I grab the view from the screen and include it into the book. Any reader of the book and user of the program can play with the application and receive similar or even more interesting results. I, as a developer, only try to guarantee the correct work of all the involved elements. The user is free to do with all the screen objects whatever he wants. With a big number of clever and curious users, the results can be more interesting than my figures in the book.
Light and Optical Borders
When a ray touches any boundary it is either absorbed, reflected, or refracted. Mirror can be flat or curved, but, regardless of its shape, at any point where ray is reflected, the angle of incidence is equal to the angle of reflection. If the ray line is known (source point and angle) and the equation for mirror surface is also known, then we can calculate the point where the ray touches the mirror and the tangent at this point. Using this tangent, we construct (at the calculated point) an imaginable flat optical border turned for the known angle, and then calculate the reflection as if the ray touched this border at the known point. Thus, for all further calculations we need a class of flat optical borders. (Absolutely the same thing happens when we deal with lenses. Only in that case, refraction happens, not reflection, so flat optical borders are designed in such a way as to be useful for both processes.)
The OpticalBorder_Flat
object is a straight segment defined by its two end points A and B. For the majority of further calculations the angle of this border is important; this is an angle from ptA
to ptB
.
public class OpticalBorder_Flat
{
PointF ptA, ptB;
double m_angle;
double m_alpha,
m_beta,
angleCritical;
double alpha_reflection;
OpticalType optical_OnPlusSide,
optical_OnMinusSide;
double indexRefraction_OnPlusSide, indexRefraction_OnMinusSide,
index_SourceSide, index_OppositeSide;
An optical border can be touched by a ray from any side, so two OpticalType
values are determined for a border. For mirrors, only the first two values from this enumeration are used; the third value is used when refraction is discussed.
public enum OpticalType { Absorption, Reflection, Refraction };
Flat Mirrors
Flat mirrors are always used to show that angle of incidence is equal to the angle of reflection. In the current example, users can play with an arbitrary number of mirrors and produce something similar to famous experiments with mirrors on Mount Wilson.
Any flat mirror (of the Mirror_Flat
class) has one reflective side. Shown as a rectangle, such flat mirror has four optical borders which coincide with the sides of rectangle. Three optical borders absorb rays; one border reflects rays which come from outside. The source of light has the shape of a flashlight. If a ray reflected from any mirror touches the flashlight, then the ray route is finished. Thus, eight segments of the flashlight border are represented with eight optical borders which absorb rays. The user can add and delete mirrors; at any moment for a system of N mirrors we have (4 * N + 8) optical borders. The ray route is calculated by the RayRoute()
method.
The code of this method is simple; you can see it in the Form_Mirror_Flat_any.cs file. Here I prefer to write about the implemented algorithm.
- Calculation is organized as an infinitive loop. At each cycle the source point of the ray and its angle are known; at the beginning these values are provided by flashlight.
- The crossing by this ray of each optical border is checked and the nearest of all touched points is determined.
- If this point is at the reflective side of any mirror, then the touched point is used as the source point for the next route leg, the angle of reflected ray is used as the source angle, and the whole loop starts again.
- If the point is at that side of optical border which absorbs rays, then the touched point is the last point of the route; the calculation is over.
- If the ray does not touch any optical border, then it is also the end of calculation.
Curved mirrors
Curved mirrors can be concave or convex. For simplification, in the course of Geometric Optics usually spherical mirrors are discussed. For them, the angle of reflected ray is easily obtained without any imaginary optical border.
This is a classical example to explain the image formation in concave mirror; you can find a similar figure in nearly every book on Geometric Optics. In this example, the user can move an object (arrow) and change its height by moving an arrow tip. Mirror is movable, resizable, and tunable.
public class Mirror_Concave : GraphicalObject
{
double m_radiusCurvature;
double m_diameter;
double m_sagitta;
double m_angle;
double alpha;
double m_thickness;
By moving upper or lower edge of mirror, its diameter is changed. By moving the central mirror part (its part on the principal axis) the radius of curvature is changed. By moving the central point of the reflective side, the mirror sagitta is changed. By any other point the whole mirror is moved.
The image is determined by the point of the rays crossing, so all routes must be calculated. Here is the code for ray number 1 which is sent parallel to the principal axis. This is part of the CalculateRays()
method from file Form_Mirror_Concave_Image.cs.
private void CalculateRays ()
{
… …
if (mirror .Point_A .Y < arrow .Location .Y &&
arrow .Location .Y < mirror .Point_B .Y)
{
Auxi_Geometry .LineCircle_Crossing (arrow .Location,
new PointF (arrow .Location .X + 3000, arrow .Location .Y),
mirror .Center, mirror .RadiusCurvature,
out ptCross_0, out ptCross_1);
ptReflection = new PointF (Math .Max (ptCross_0 .X, ptCross_1 .X),
arrow .Location .Y);
if (cxArrow < ptReflection .X - 10)
{
ptsRay_1_Horizontal .Add (arrow .Location);
ptsRay_1_Horizontal .Add (ptReflection);
angleTangent = Auxi_Geometry .Line_Angle (mirror .Center,
ptsRay_1_Horizontal [1]) - Math .PI / 2;
angleReflection = 2 * angleTangent;
ptsRay_1_Horizontal .Add (Auxi_Geometry .PointToPoint (
ptsRay_1_Horizontal [1], angleReflection, 4000));
if (arrow .Location .X > ptFocal .X)
{
ptRay_1_FarRight = Auxi_Geometry .PointToPoint (
ptsRay_1_Horizontal [1],
angleReflection + Math .PI, 4000);
}
}
}
… …
- Points A and B in the shown code are the upper and lower points of the reflective side.
ptReflection
is the point of reflection on mirror - For some arrow positions the reflected rays diverge, but their lines converge behind mirror; for such case, there is different calculation for the last point of the route.
Refraction
Is it possible at all to demonstrate something new in the established course of Geometric Optics? The explanation of refraction is nearly standard and is illustrated with the same examples in all textbooks, but I think that here you will find an addition of something unusual. When we look not straight through the glass, but at some angle, the whole picture shifts a bit. This happens because at the air–glass boundary, light bends either to normal or away from normal. This bending depends on the optical density of materials on both sides. When ray goes through the glass, the bending on first boundary is compensated by the bending on the second. The emerging ray is parallel to the original, but there is some shift between two rays (figure 1.14). When initial ray is sent at the narrow side of the glass plate, then we receive an excellent demonstration and explanation of optical cable (figure 1.16b). Ray route at figure 1.15 is really strange. I never thought about the possibility of such route and received it by moving and rotating the flashlight.
| | |
Fig.1.14 Refraction on the second boundary sets the out coming ray parallel to the original.
| Fig.1.16b Ordinary refraction happens at the first and last points; at all the intermediate points the total internal reflection occurs.
| Fig.1.15 A strange route for the ray which is sent closer to the end of the vertical side.
|
All these routes are calculated by the RayRoute()
method in the Form_GlassPlate.cs.
Suppose that you have an optical border of the OpticalBorder_Flat
class and a ray with the known source point, angle, and length. Then the method OpticalBorder_Flat.Interaction (ptRaySource, angleRay, lenRay)
returns the results of the ray interaction with this border. The returned result belongs to the RayBorderInteraction
class.
public class RayBorderInteraction
{
InteractionType typeInteraction;
PointF ptTouch;
double m_angleOut;
The type of interaction is some value from the InteractionType
enumeration.
public enum InteractionType { NoContact, Absorption, Reflection, Refraction };
Glass plate is shown as a rectangle, so there are four optical borders along the sides of this rectangle. In the current example the ray cannot turn back and touch the flashlight, but in order to use the standard procedure, eight optical borders are organized along the flashlight border.
The route calculation is again organized as an infinitive loop. All optical borders are numbered. At each cycle the crossing of all borders is checked and the nearest touch point is determined together with the number of the corresponding optical border (iNextSource).
If no optical border is touched, then calculation is over.
public void RayRoute ()
{
… …
while (true)
{
… …
if (iNextSource < 0)
{
ptsRay .Add (Auxi_Geometry .PointToPoint (ptSource, angle, len));
break;
}
If any optical border is touched, then there is absorption, refraction, or reflection.
else
{
PointF ptTouch = ray_interact [iNextSource] .TouchPoint;
ptsRay .Add (ptTouch);
if (ray_interact [iNextSource] .InteractionType ==
InteractionType .Absorption)
{
break;
}
else if (ray_interact [iNextSource] .InteractionType ==
InteractionType .Refraction)
{
angle = ray_interact [iNextSource] .AngleOut;
… …
}
else
{
angle = m_border [iNextSource] .Angle_Reflection (angle);
… …
- In our case of glass plate, absorption never happens.
- If ray touches the glass plate, then there is at least two touch points. At the first touch point, ray enters the glass; at the last touch point, ray emerges from glass; at these two points refraction happens.
- If ray comes to the boundary of two materials from the side of optically denser medium and the angle of incidence exceeds critical angle for this boundary, then total internal reflection happens. If in our case we have more than two touch points, then total internal reflection happens on all points except the first and the last. You can see this at figures 1.15 and 1.16b. I think that many readers will be amazed by the case from figure 1.15.
To discuss refraction and total internal reflection, the case of air – water boundary is often used. Let us look at more interesting case which is demonstrated with the Form_Aquarium.cs. Suppose that a family of parents and kids are on a visit to oceanarium. This oceanarium is constructed in such a way that visitors can stay at different levels on the left of glass wall while half of the right volume is filled with water. From the points of Optics and programming, our oceanarium has four optical borders; its easy to understand the positions of these borders by the names which they receive at the moment of construction.
public void DefineOpticalBorders ()
{
PointF [] pts = m_wall .BorderLoop;
m_border [0] = new OpticalBorder_Flat ("Air_Glass_left", pts [0], pts [3],
indexRefraction_CrownGlass, indexRefraction_Air);
PointF ptM = Auxi_Geometry .Middle (pts [1], pts [2]);
m_border [1] = new OpticalBorder_Flat ("Glass_Air_right", pts [1], ptM,
indexRefraction_Air, indexRefraction_CrownGlass);
m_border [2] = new OpticalBorder_Flat ("Glass_Water_right", ptM, pts [2],
indexRefraction_Water, indexRefraction_CrownGlass);
m_border [3] = new OpticalBorder_Flat ("Air_Water", ptM,
new PointF (ClientSize .Width, ptM .Y),
indexRefraction_Air, indexRefraction_Water);
RayRoute()
method is identical to the previous case.
When you look from the top in the way shown at figure 1.17, then there are three points of refraction. The first two points are the same as at figure 1.15; it is a classical case of looking through the glass at some angle. The third point demonstrates another classical case from all the textbooks which explains that when you look from the bank on the water, you see not the things at the direction of your sight because the ray bends.
Now visitors of our oceanarium go down to have a better look at the water creatures. A grown up sees something amazing in front (figure 1.18a) and tells kids to look there. They try; maybe they will, but chances are high that they miss because of those turns of the ray at every touch point (figure 1.18b). Kids try to see the mentioned creature and slightly change the angle of their look; instead of something just near the glass wall they have a chance to see creatures far away at the bottom of oceanarium (figure 1.18c). Kids were not even thinking about that part of oceanarium, but they can see it.
| | |
Fig.1.18a This ray is nearly straight.
| Fig.1.18b It is not easy to reach exactly the same spot in the water with such refraction.
| Fig.1.18c This ray reaches places which are somewhere far away from its initial direction.
|
And what do water creatures see from their world? Suppose that there are some mermaids performing or oceanarium workers / scientists doing something. What do they see? If they look at relatively small angle of incidence, then they can see something on the outer side of glass wall (figure 1.19a). But it is enough to look a bit higher, thus increasing the angle of incidence, and the whole world on the left becomes inaccessible, though the real picture greatly depends on the angle of incidence (figures 1.19b, 1.19c, and 1.19d)
| | | |
Fig.1.19a Two points of ordinary refraction.
| Fig.1.19b Three points of ordinary refraction and one point of total internal reflection.
| Fig.1.19c The same set of refractions and total internal reflection, but the last ray leg bounds to the glass.
| Fig.1.19d First point of ordinary refraction and then a set of total internal reflections.
|
Situations which are shown at these figures are fixed, while their appearance is the result of my playing with movable and resizable objects of the program. I think that if you spend some time, you can receive even more interesting results. This is a result of turning a simple program into user-driven application. I give users an instrument and put no restrictions on using it. Users can be much more skillful than me in thinking out the most interesting cases, so they will achieve the results which are more interesting than demonstrated here. That is why I always underline that all scientific programs must be turned into user-driven. Simply because scientists are much more skilful in their areas than developers of the programs these scientists have to use.
Up until now the demonstrated examples used the monochromatic rays. Sun sends white light which is a composition of seven different colors. There are seven slightly different wavelengths. When they reach the boundary of two mediums, these seven rays bend on slightly different angles because they have different indices of refraction. Dispersion is discussed in the book with the help of three different examples, but in this article I want to mention another one.
There was that famous scene in Pollyanna book by Eleanor H. Porter. "It had become a fairyland--that sumptuous, but dreary bedroom. Everywhere were bits of dancing red and green, violet and orange, gold and blue. The wall, the floor, and the furniture, even to the bed itself, were aflame with shimmering bits of color." Did you ever think about the cause of those colored spots?
Pollyanna hanged pendants in the way of a sunlight. In the next example Form_Prism_RegularPolygon.cs pendant is shown as a regular polygon; polygon is movable, resizable, and rotatable; also the number of vertices can be changed. Familiar flashlight is used as the source of light. Because we’ll need to change the wavelength (the color) without accidental changing anything else, the color selection is done through menu not at flashlight but at empty places.
Optical borders are organized on all segments of the polygon border plus the standard eight optical borders for flashlight.
public void DefineOpticalBorders ()
{
PointF [] pts = prism .Vertices;
int nForPrism = prism .VerticesNumber;
m_border = new OpticalBorder_Flat [nForPrism + 8];
for (int i = 0; i < nForPrism; i++)
{
m_border [i] = new OpticalBorder_Flat ("Prism_" + i .ToString (),
pts [i], pts [(i + 1) % nForPrism],
indexPrism, indexRefraction_Air);
}
… …
You can move and rotate objects; plus you can change the color. For some combinations of angles and sizes the results for different colors can be nearly identical because the difference in indices of refraction is very small, but in some cases even this small difference causes the fantastic scene which Pollyanna saw. Figures 1.24 explain this for the same geometry of flashlight and prism.
| | |
Fig.1.24a Red light has a single point of internal reflection and then comes out.
| Fig.1.24b Blue light comes out after 13 internal reflections.
| Fig.1.24c Violet light makes nearly four circles inside and comes out after 25 internal reflections.
|
Figure 1.24a shows the route of the red color. There is a single point of total internal reflection, and on the next point of boundary contact red light leaves the prism.
Next four colors – orange, yellow, green, and cyan – go near by, have a single point of total inner reflection each, and leave the prism at nearly the same point. But the blue color doesn’t copy this pattern. At the point where previous five colors left the prism, the angle of incidence for blue color is above its critical angle, so the blue color is again reflected inside. After it, more internal reflections happen, and blue light comes out after two circles inside and at absolutely different angle (figure 1.24b).
Violet light makes nearly four circles inside and comes out at its own angle (figure 1.24c). Because different lights come out at different angles, we obtain the situation when places around are "…aflame with shimmering bits of color."
I want to remind again that everything is movable and resizable in these programs, so you can play and receive even better results than demonstrated in the book. You can take all the codes and construct more exciting examples.
I hope that this program can be helpful in understanding and learning the laws of Geometric Optics. I also hope that similar programs can be very useful in many other areas.
Dr. Sergey Andreyev