Waves

Waves

Background

The wave effect is one of the most interesting (if not the most interesting) effects. What seems on the surface like just another simple coding routine is actually very complicated compared to any other effect explained on this site. To understand the wave algorithm, it is necessary to review some basic principles of optics.
Rand's Face
Figure 1.1
Distorted Face
Figure 1.2

All clear substances have a physical property known as an index of refraction. The law of refraction states that:

n1*sin(theta1) = n2*sin(theta2)

In which n1 and n2 are the indices of refraction of the two materials. Air, for example, has an index of refraction of about 1, as does a vacuum. The bending of light will be greatest, therefore, in substances with higher indices of refraction. For comparison, the value for water is 1.33 and the value for diamond is 2.42. The image in figure 1.1 is a picture of my face. The image in figure 1.2 is the same image as viewed through two water waves created with our applet.

How does refraction apply to waves?

Since the user is viewing the wave pattern from above, he or she is viewing light rays that have traveled from some spot on the image below the waves. Refraction will cause the light to bend by different amounts depending on the slope of the wave beneath each pixel.

This means that for each pixel, the slope of the wave must first be determined. The easiest, most reliable way to do this is to take the absolute value of the tangent of the arcsine of the wave's height at the pixel divided by the wave's amplitude. You may have to think about that for a while to see how it works. I certainly did :)

Let's do some math!

Now, we're done with the easy part. Once the slope has been calculated, it is now necessary to determine the horizontal and vertical difference between the current pixel and the pixel that is the light source. To accomplish this, I derived an equation for the difference if the wave was straight (not at an angle) and then took the rotation into account. The equation is:

xdiff = pixelHeight / ( tan(-arctan(-1/(slope)) + arcsin(sin(theta1)/indexOfRefraction) ) )

Don't worry too much about that equation, because it is very complicated and the derivation is not obvious, in addition to being somewhat lengthy. Once this has been calculated, you simply take the color value of the pixel plus the vertical and horizontal differences and replace the original pixel with it.

Let's try it!

If you've got a Java-enabled browser, then you're in luck. We have designed an applet which lets you play with not one but two (yes two) waves of various amplitudes, wavelengths, and directions. You can also change the medium that the wave is passing through and use intensity instead of or in addition to the refraction:
Show Me the Java
Return to main page.