Saturday, July 23, 2011

Pulling numbers into a range

In my recently published book, Sun Position, there are several astronomical calculations that result in angles well outside the range of 0 to 360 degrees. For example, there's a rather complicated formula for the mean longitude of the earth, or the number of degrees of angular travel for the earth as it orbits the sun, accurate for past, present, and future moments in time. The angle is calculated by a polynomial that returns a number that increases approximately by 360 for every year added to the input value. As a result, the angular position of the earth in its orbit around the sun is calculated as so many thousands of degrees, a number that's hard to work with.

The most straightforward way to convert this angle to something more usable is to repeatedly subtract 360 degrees until the result is brought into the range 0 to 360, although this is computationally inefficient. A better approach, and the one used most often, is to divide the large angle by 360, take the integer part of the result and subtract that number times 360 from the original value.

This technique works pretty good to bring large angles into the range 0 to 360, but sometimes, as in the case of an elevation angle, the range -180 to +180 is more appropriate. Also, in some calculations the angles are in radians instead of degrees, so ranges of 0 to 2*PI or -PI to +PI are more appropriate.

So, I decided to create a flexible function that could handle all these cases with ease. Here's the result, in Visual Basic syntax. It works very well...


Public Function Range(ByVal x As Double, ByVal rMin As Double, ByVal rMax As Double) As Double
   Dim delta As Double = rMax - rMin
   Return (((x - rMin) Mod delta) + delta) Mod delta + rMin
End Function


To use this function, pass it the number to be processed, the low end of the desired range, and the high end of the range. It works well with negative numbers, radians, degrees, or other number ranges. Here are a few examples...

Range(1234.56789, 0, 360) = 154.56789
Range(-456.7, -180, 180) = -96.7
Range(1234.56789, -3.1415926, 3.1415926) = 3.0635908
Range(1234.56789, 0, 1) = 0.56789

No comments:

Post a Comment