HTML5 is supported by more and more browsers. It has a nice feature called the ‘canvas’ element. It is an element on which you can ‘paint’ using e.g. JavaScript. I experimented with this new canvas element. You can view the experiments (clock, 3D-axis and rotation, ray tracer) and view the source too! The ray tracer should be activated in Chrome or Safari as Firefox and Internet Explorer tend to be (very) slow.

]]>As many roads lead to Rome multiple ways are possible to this simulation. One could model the sun, earth, maybe more and start ray tracing. This approach would include solar eclipses but is quite heavy by means of the load on the processor. Because of the number of calculations involved in ray tracing is quite high. The way I choose to describe fully in this article is one close to it. Using vectors pointing from a sphere (earth) to a point (sun) I map a Mercator projected map of the world on the sphere. The challenges included are the yearly orbit of earth around the sun and it’s 23.5° tilted 24 hour spin.

About a decade ago I made a similar program in highschool. I didn’t know vectors and trigonometry then as I do now. Back then I used to have the map of the world where for each longitude (the ones parallel to the equator) I calculated sunset and sunrise times for that longitude. This way I knew when to start painting night over the daylight map I had. This result was pretty accurate and an algorithm to determine those solar times is not hard to implement. This time I used another more advanced approach to the problem.

First let us define a mathematical 3D space, with three axis: (pointing from left to right), (pointing up) and (pointing into your monitor). Pointing directions are given to help your imagination. Axis point from small (negative infinite) to big (positive infinite), they intersect at .

Define a sphere on point , with a radius of 1. This will be the earth. The funny thing is that for every point(x,y,z coordinate) on the earth, because the earth is centered around , automatically is the same a the vector pointing orthoganally away from the earth starting on that point. This comes in handy when we do calculations later on.

We don’t need the sun for this method. We only need the direction to it from the earth. So define a vector *S* which points in the direction of the sun from . To do this we must use sine and cosine. On time the direction of the sun will be , which is a vector pointing to the right. On (hour) that should be pointing right . The same goes for 6 o’clock am and pm, being respectively and . This gives us insight that the direction to the sun can be given as ( should be scaled to a value from 0 to 1, so we need to divide by 24):

With this approach we actually make the sun rotate around the earth.

The above formula still is not complete. The axis around which the earth is spinning is not orthogonal to the plane defined by the orbit of the earth around the sun. It is tilted 23.5°. This is how we get the four seasons on earth of course. To model this a nice trick can be applied to *d*. We know that on or closely around June 21th the sun is right above the 23.5° latitude (Tropic of Cancer), the summer solstice. From here it takes a sine with a period of a year to go to -23.5° and back again. June 21th is the 172th day of the year. The standard cosine function has the form:

We can simply fill this out. The must be 23.5, is , is -172 and equals 0. If you define the observable tilt (because the real tilt will always be 23.5) and is the day of the year:

Now this observable tilt is the angle there is between what is the real direction to the sun and the already calculated direction *d*. To calculate the vector ( component, pointing up or down) which should be added to to get the real direction you can use tangens.

Then the real direction vector is the addition of * *to :

Using the dot product (or scalar product or inner product) you can calculate the angle between two vectors. Or, if the vectors are both normalized (length = 1) it is the projection of the one vector onto the other. So if we calculate the dot product for every normal vector from the surface of the earth () with we should get some meaningful results.

If the the sun is in another direction so is pointing to the night side of the earth. If that piece of earth recieves solar light.

We have a 2D map (Mercator projection) we need to map on the 3D sphere. We need to do this to determine which we need to calculate dot products for. To avoid confusion, lets call *x* and from the 2D map and . We can iterate for each and each for each and map it to a in 3D. To do this we need to determine phi (, logitude: )and theta (, latitude: ). In the iteration ( is the height of the map and is the width of the map):

Now and map to as follows:

Now we can for each coordinate on the map if it should be displayed as day or night.

Because you know the angle the sunlight makes with the earth’s surface you can make add some shading by making it increasingly dark on the edges of the day. It the dot product of and is smaller than 0.1 () the point is in dusk or dawn and you could mix day and night as a gradient to make the difference between them look more fluently. Another joke is the reflection of the sun: if the product is greater than, let’s say, 0.95 () the sun is approximately orthogonally above that coordinate an you could make it more white to have it look like the sun is reflecting in the map.

A demontration of this method is available at the edesign example site. There are a number of assumptions done and restrictions set while creating this demo.

- I assumed the solar rays are parallel. The distance from the sun to the earth is huge, but it is actually wrong to assume rays are parallel. They are only by approximation so it is good enough for this simulation.
- Because of this assumption, the night ’starts’ exactly at the half of the world in the shade while actually this is different. The sun is far bigger than the earth and therefor some rays should be able to reach the shadow half of the earth (near the limit depicted in the first image). By approximation I eliminated this too.
- Timing is not very accurate. As well as for the 24h clock as for the solstices rough estimates are used.
- A perfect sphere is taken as world. No fattening is modelled (polar radius should be smaller than equatorial radius).
- The ‘fun with shading’ should implement something to make land mass not reflect sunlight.