When I was working for a small wind turbine manufacturer I was asked to calculate the number of hours per year the houses in the neighborhood of our prototype wind farm would be exposed to shadow flicker from our wind turbine. Now, there are software that calculates this sort of thing with a few clicks of the mouse (the dominant code beeing WindPro). However, these programs cost money, and they are no fun. Instead I solved the problem myself. And to do that I first had to immerse myself in the theory of sundials.
First consider a flagpole casting a shadow on a flat field. There are only a few parameters that influence where the tip of the shadow will be at a particular time. There are some astronomical parameters, namely: the earth axial tilt, the earth rotational speed, the length of the solar year, the eccentricity of the orbital ellipse, and the angle between the major axis of the orbital ellipse and the line of solstices.
Then there are some parameters of the site: height of pole, latitude and longitude. And there is a convention where the year is said to begin relating to the winter solstice.
The rest is a matter of geometry really. Basically one must keep track of exactly how earth is facing the sun at any particular instant in time.
Coordinate tranformations
This is how I think about it. I want to find a transformation from geographic coordinates (which rotate with earth) to a coordinate system with origo in the center of the earth that always has the sun in the direction of the y-axis and the z-axis normal to the orbital plane. In this system it should be easy to find the tip of the shadow by finding the intersection between the line passing from the sun, through the tip of the pole and the sphere that is earth. Once this is done we go back to geographic coordinates by applying the inverse tranformation.
To implement this we first want a coordinate transformation from the geographic coordinate system (longitude $\phi$, latitude $\delta$, height $h$) rotating with earth to a cartesian system rotating with earth. This is a simple adaption of the spherical coordinate transformation. The only difference being that the latitude replaces the normal angle from the north pole.
$$ \begin{array}{rcl} x & = & (R+h) \sin(\pi/2-\delta)\cos \phi \ y & = & (R+h) \sin(\pi/2-\delta)\sin \phi \ z & = & (R+h) \cos (\pi/2 - \delta) \ \end{array} $$
What we want to do next is to transform a point expressed this way to a nonrotating coordinate system. The transformation matrix for rotation about the z-axis is
$$ R_z(\Omega t) = \left(\begin{array}{ccc} \cos \Omega t & -\sin \Omega t & 0 \ \sin \Omega t & \cos \Omega t & 0 \ 0 & 0 & 1 \end{array}\right) $$
where $\Omega$ is the rotational speed of earth $2 \pi / 86164.09890369 $ rad/s.
Next we want to express this in a system aliged with the earth orbital plane. Thus we want to rotate about the universal y-axis by the axial tilt angle $\alpha = 23.4{}^\circ$. The transformation matrix for this rotation is
$$ R_x(\alpha) = \left(\begin{array}{ccc} 1 & 0 & 0 \ 0 & \cos \alpha & - \sin \alpha \ 0 & \sin \alpha & \cos \alpha \end{array} \right) $$
Finally we want to rotate this system so we face the sun.
$$ R_z(-\theta(t)) = \left( \begin{array}{ccc} \cos \theta(t) & \sin \theta(t) & 0 \ -\sin \theta(t) & \cos \theta(t) & 0 \ 0 & 0 & 1 \end{array} \right) $$
where $\theta(t)$ is the orbital angle. This is a function that must be computed based on orbital mechanics.
The total transformation from ($\phi$,$\delta$) is thus
$$ \left(\begin{array}{c} X \ Y \ Z \end{array}\right) = T(\phi,\delta) = R_z(-\theta(t)) R_x(\alpha) R_z(\Omega t) \left(\begin{array}{c} (R+h) \sin(\pi/2-\delta)\cos \phi \ (R+h) \sin(\pi/2-\delta)\sin \phi \ (R+h) \cos (\pi/2 - \delta) \end{array}\right) $$
The inverse of this tranformation is obtained by
$$ \begin{array}{rcl} h & = & \sqrt{x^2+y^2+z^2}-R \ \phi & = & \mbox{arctan}\left(\frac{y}{x}\right) \ \delta & = & \pi/2 - \mbox{arccos}\left(\frac{z}{r}\right) \end{array} $$
where $$(x,y,z)$$ is obtained by inversing the rotations
$$ \left(\begin{array}{c} x \ y \ z \end{array}\right) = \left(R_z(-\theta(t)) R_x(\alpha) R_z(\Omega t)\right)^{-1} \left(\begin{array}{c} X \ Y \ Z \end{array}\right) $$
Intersection between ray and earth surface
Assume the earth surface is a perfect sphere centered in origo. Also assume all light rays from the sun are coming in the -Y-direction. Now consider a point $\vec{p}$ representing the location of the flagpole tip. The tip may or may not cast a shadow on earth.
To find the location of the shadow simply apply the formula for line sphere intersection
$$ \ d = -\hat{Y} \cdot \vec{p} - \sqrt{\left(-\hat{Y} \cdot \vec{p}\right)^2-\vec{p} \cdot \vec{p}+R^2} $$
where $R$ is the earth radius and $d$ is the distance from $\vec{p}$ to the intersection. $\hat{Y}$ is a unit vector in the Y-direction. If $d$ is real and greater than zero the location of the shadow is
$$ \vec{s} = \vec{p} - d \hat{Y}. $$
I have implemented this theory as a python module. The source is over at gitHub
A sundial for my back yard
As an application of this theory I have decided to construct a sundial custom made for my backyard. This is a bit of a project of its own and I will delay the details for a later blog. The following picture is what I have come up with so far. This sundial shows approximate date and also takes daylight saving into account.