About SunSphere

Jars Registered The SunSphere applet was "Rated Top 5% WebApplet" by JARS.
If you find bugs in this program (or improvements), please contact me.

SunSphere displays an image of the earth showing the sunrise and sunset terminator. It uses your local timezone (which must have been set correctly) to approximate your local longitude and give the impression that you are looking down on the earth from above the equator.

SunSphere requires Java 1.1 support.

SunSphere is documented in the following sections.

Recent improvements and Known Bugs

This is slightly new version of SunSphere with the following (presumable) improvements: Please accept my apology for the following bugs.

Adding SunSphere to Your Home Page

You may use SunSphere in your personal, non-commercial, home page. In doing so, you understand that I make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for any incidental or consequental damages in connection with or arising out of the use of the information or program.

To add SunSphere, add the following HTML to your web page:

<applet
  codebase="http://www.vmeng.com/minow/sunsphere/MRJ"
  archive=SunSphereMRJ.jar
  code="org.minow.applets.sunsphere.SunSphere.class"
  width=190
  height=220
>
<param name=bgcolor value="#FFFFFF" >
<param name=textcolor value="#000000" >
<param name=autostart value="true" >
<param name=latitudegrab value="false" >
<param name=latitude value ="0.0" >
<param name=latitudeincrement value="15.0" >
<param name=latitudespin value ="0.0" >
<param name=longitude value="123.45" >
<param name=longitudeincrement value="15.0" >
<param name=longitudespin value="1.0" >
<param name=spininterval value="1000" >
The SunSphere Applet is displayed here if your browser supports Java.
</applet>
You may specify the following optional parameters.
bgcolor
A value that matches the background color of your web page. A value of #000040 looks nice, for example.
textcolor
The color for the text. It should be appropriate for your chosen background color.
autostart
Specify true or false. If true, the image starts rotating immediately.
latitudegrab
Specify true or false. If true, the grabbing the globe with the mouse lets you move or spin it in both latitude (North/South) and longitude (East/West). This requires about ten times as much computation per pixel for each rotation step.
latitude
The latitude of the center of the image. The default is 0 degrees.
latitudeincrement
The number of degrees to rotate the image when you click on the North or South buttons. The default is 15 degrees.
latitudespin
The number of degrees to spin the image North or South when you start spinning. The default is 0 degrees. Spinning is very slow if this is non-zero
longitude
The initial longitude of the midpoint (i.e., the location of the observer). The default computes the initial longitude based on the local timezone. The value should be in the range -180.0 to +180.0, where positive values are East of the prime meridian.
longitudeincrement
The number of degrees to rotate the image when you click on the East or West buttons. The default is 15 degrees.
longitudespin
The number of degrees to rotate the image at each rotation update. The default is +1.0 degrees.
spininterval
The time in milliseconds between image rotation. If you make this too short, the applet will require too much computer time. The minimum is 10 msec. but you can make it shorter for testing by using the configuration dialog.

Computing Sunrise, Sunset, and Twilight

Sunrise is the time when the apparent altitude (H) of the upper limb of the Sun will be -50 arc minutes. This includes compensation of 34 arc minutes for atmospheric refraction and 16 arc minutes for the sun's semi-diameter. Twilight, as used here, is the time when the sun's apparent altitude is six degrees below horizon. This is the time of "civil" twilight. To compute the time, the program starts with an estimate of noon, and iterates towards morning or evening until the actual and predicted times are satisfactorily close. Ignoring some complications, the algorithm is as follows.

JD = Modified Julian Date The Modified Julian Date is the number of days since midnight, November 17, 1858.
UT = 0 Set the estimated event (sunrise, sunset, twilight) time to midnight.
UT0 = 0 Set the computed event (sunrise, sunset, twilight) time to noon.
while (abs(UT - UT0) > 0.0008) { Continue until the the estimates are satisfactorily close together.
  T <- (JD + UT/24 - 2451545.0)/36525. Using the current time estimate, compute the number of centuries since the ephemeris epoch of January 0, 2000.
  L <- 280.460 + 36000.770 * T Compute the solar mean longitude in degrees.
  G <- 357.528 + 35999.050 * T Compute the solar mean anomaly in degrees.
  M <- L + 1.915 * sin (G) + 0.020 * sin (2*G) Compute the ecliptic longitude in degrees.
  e <- 23.4393 - 0.01300 * T Compute the obliquity of the ecliptic in degrees.
  E <- -1.915 * sin (G)
    - 0.020 * sin(2*G)
    + 2.455*sin(2*M)
    - 0.053 * sin(4*M)
Compute the equation of time.
  GHA <- 15*UT -180 + E Compute the Greenwich Hour Angle in degrees.
  DEC <- arcsin(- sin (e) * sin (M)) Compute the the sun's declination in degrees.
  HA <- arccos(
    (sinHorizon - (sinLatitude * sin(DEC))
    / (cosLatitude * cos(DEC)))
   )
Compute the hour-angle at UT (the current estimate)
  UT <- UT0
    - (GHA + longitude + (riseSet * HA)) / 15.0
Compute the time of sunrise, sunset, or twilight. riseSet is +1.0 for morning (rising) and -1.0 for evening (setting). The result is in hours.
} Continue until the UT and UT0 estimates are close together.
return (UT) Return the computed event time.

Creating the Sunrise Image

The image is a map of the world stored as a rectangular array of pixels. Technically, this is called a Plate Carrée or equirectangular projection. It is a poor choice for a map, but a good choice for the underlying image as it is exceedingly simple to convert between latitude/longitude and pixel coordinates. For example, if the image is 360 pixels wide, every pixel column represents a single degree of longitude.

To show twilight and night, the program shades the map by computing the time of sunrise and sunset at the prime meridian (0° longitude) (i.e., Greenwich, England) for every degree of latitude. Since Java provides the Universal Time, it is a simple matter to convert the sunrise time and current Universal Time to the longitude of the the sunrise terminator. The program computes sunrise, sunset, and twilight for every latitude represented in the original image, sorts the data so it progresses across the map, and uses a Java image filter class to create a properly-shaded image.

SunrisePixels.java performs this computation once a minute. After running, the program redraws the map. It is fairly compute-intensive.

Turning the Sunrise Image into a Globe

Before drawing the image on the display, it must be converted from the equirectangular form to a globe (a sphere projected onto the two-dimensional display). Since we want to be able to rotate the image, this must be fast. To do this, SunSphereData.java builds two vectors that pre-compute the trignometric conversion. Each element in these vectors corresponds to a single pixel in the sphere that will be displayed. One vector has the latitude in the original image that will be drawn on this pixel. The other vector has the adjustment to the original image longitude that depends on this latitude. The algorithm underlying this computation was defined in "Map Projections, a Working Manual"

When these vectors have been computed, the program can rotate the image very quickly in the East to West direction, as it doesn't need to recompute the trignometric "sphere to circle" projection. Unfortunately, to rotate North or South, the vectors must be rebuilt whenever the latitude changes. Can you do better?

Spinning the Globular Image (Quickly)

SunSphereCanvas.java manages image drawing. This class also detects mouse clicks and dragging. When the mouse moves across the image, it revisits the trignometric functions to convert the mouse pixel coordinates to their corresponding latitude and longitude. As this changes, it rotates the globe as needed. If the mouse is moving when the user releases the button, the earth spins in the requested direction (and speed). To make the program run quickly, only longitude can be changed (but you can enable latitude dragging using the option dialog.)

Converting Pixel Coordinates to Latitude and Longitude

In order to locate the mouse with respect to the underlying globe, the mouse's pixel coordinates are converted to latitude and longitude using the orthographic projection formula described by John P. Snyder in "Map Projections -- A Working Manual". U.S. Government Printing Office. Page 148-150:

pixel = mouse point Detemine the location of the mouse point with respect to the sphere. This value ranges from zero to the sphere diameter, with increasing values to the right and down.
x = (double) (pixel.x - sphereRadius); Convert the horizontal pixel coordinate to a value that ranges from (-radius) to (+radius) from left to right.
y = (double) (sphereRadius - pixel.y); Convert the vertical pixel coordinate to a value that ranges from (-radius) to (+radius) from bottom to top. Note that this is opposite the Java coordinate convention.
rho = sqrt((x * x) + (y * y)); Compute the length of the vector from the origin to the indicated point. If this is greater than the radius of the sphere, return an error. Alternatively, you can force the value to the radius. If rho is zero, the user clicked on the origin: return latitude 0.0, longitude 0.0 to avoid computing arctan(0.0 / 0.0) below.
C = arcsin(rho / sphereRadius);
latitude = arcsin((y * sin(C)) / rho);
longitude = arctan((x * sin(C)) / (rho * cos(C)));
Compute the latitude and longitude with respect to the origin. As noted above, the algorithm must detect a click on the origin to avoid dividing by zero.

Java Source Files

Here are the Java source files used by the applet.
AlertDialog.java
AlertDialog.java is the parent class of InfoDialog.java.
DateEntryPanel.java
DateEntryPanel.java lets you specify a specific display date.
DayTimeEntryPanel.java
DayTimeEntryPanel.java lets you specify a specific time as a number of days, hours, minutes, and seconds.
DegreeEntryPanel.java
DegreeEntryPanel.java lets you specify a specific location as a number of degrees, minutes, and seconds.
GraphicsButton.java
GraphicsButton.java is the parent class of SunSphere's image-based buttons. This is a general class for active (i.e., clickable) components.
InfoDialog.java
InfoDialog.java is a simple dialog used for error reporting.
IntegerField.java
IntegerField.java is used by several dialog panels to manage the user interaction for a digit-only field.
It is not quite correct, but good enough for now.
LatitudeField.java
LatitudeField.java is a DegreEntryPanel that lets you enter a location's latitude.
LongitudeField.java
LongitudeField.java is a DegreEntryPanel that lets you enter a location's longitude.
PropertyPanel.java
PropertyPanel.java is the parent of a number of user-interaction panels that fire PropertyChangeEvents when the user changes the value..
OptionBorder.java
OptionBorder.java is a decorative border for SunSphereOptionDialog.java..
SunrisePixels.java
SunrisePixels.java uses the ephemeris calculations in SunSphereRiseSet.java to compute the shape of the sun's terminator (the sunrise and sunset lines) and modifies a map of the earth to show the area. SunrisePixels does not draw the map: it constructs a pixel vector for use by other classes.
SunSphere.java
SunSphere.java manages the overall applet, responding to mouse clicks, dialog updating, and updating the image as needed.
This is beginning to grow out of control. Remind me to stop listening to friendly requests for new features.
SunSphereBeanInfo.java
SunSphereBeanInfo.java is used by Java Beans utilities to determine public methods and capabilities.
This is incomplete: many new features aren't described in the BeanInfo. Later, perhaps.
SunSphereButton.java
SunSphereButton.java draws the image-based buttons.
SunSphereCanvas.java
SphereCanvas.java transforms the pixel vector created by SunrisePixels.java into the spherical image that will be displayed.
SunSphereConfigMRJ.java
SunSphereConfigMRJ.java has static (global) data for the Apple MRJ Software Development Kit.
SunSphereData.java
SunSphereData.java computes the image that will be drawn..
SunSphereEastButton.java
SunSphereEastButton.java defines the East (right) button.
SunSphereInfoButton.java
SunSphereInfoButton.java defines the Info (dialog) button.
SunSphereNorthButton.java
SunSphereNorthButton.java defines the North (up) button.
SunSphereOptionDialog.java
SunSphereOptionDialog.java is a simple dialog that lets the applet user change the spin rate and other parameters.
SunSphereParameters.java
SunSphereParameters.java has static (global) strings.
SunSphereRiseSet.java
SunSphereRiseSet.java computes the sunrise, sunset, and twilight times for a specific date and latitude, and longitude using an algorithm adapted from The Explanatory Supplement to the Astronomical Almanac, P. Kenneth Seidelmann, Ed. ISBN 0-935702-68-7. At one time, this algorithm was described on the USNO Time Services web page. The explanation below was adapted from that web page.
SunSphereSouthButton.java
SunSphereNorthButton.java defines the South (down) button.
SunSphereSpinButton.java
SunSphereEastButton.java defines the Spin and Stop buttons.
SunSphereWestButton.java
SunSphereEastButton.java defines the West (left) button.
TimeEntryPanel.java
TimeEntryPanel.java lets you specify a specific time as a number of hours, minutes, and seconds.
Utility.java
Utility.java has a large number of static computation and data formatting methods.
EarthImage360.gif
EarthImage360.gif is the image that underlies the spherical map of the earth. It is a GIF conversion of the world map that is included in the Macintosh Scrapbook. Copyright © Apple Computer Inc. Used by permission.
SunSphereMRJ.jar
This archive contains the executable classes.
SunSphereMRJ.html
contains the web page source that displays the SunSphereMRJ applet..
SunSphereInfoMRJ.html
contains the web page source that describes the SunSphereMRJ applet..

References and Additional Information

Copyright © 1996-1998 Martin Minow. All Rights Reserved.
Permission to use, copy, modify, and redistribute this software and its documentation for personal, non-commercial use is hereby granted provided that this copyright notice and appropriate documentation appears in all copies. This software may not be distributed for fee or as part of commercial, "shareware," and/or not-for-profit endevors including, but not limited to, CD-ROM collections, online databases, and subscription services without specific license. The author makes no expressed or implied warranty of any kind and assumes no responsibility for errors or omissions. No liability is assumed for any incidental or consequental damages in connection with or arising out of the use of the information or program.