Download or view planarSundial.frink in plain text format
// This allows the construction of a planar sundial of any given orientation
// and inclination.
//
// It also draws a scaled horizontal line indicating the size of the gnomon.
//
// See Jean Meeus, Astronomical Algorithms, Chapter 58 for description.
calculatePoint[lat, D, a, z, H, delta] :=
{
P = calcP[lat, D, a, z]
Q = sin[D] sin[z] sin[H] + (cos[lat] cos[z] + sin[lat] sin[z] cos[D]) cos[H] + P tan[delta]
Nx = cos[D] sin[H] - sin[D] (sin[lat] cos[H] - cos[lat] tan[delta])
Ny = cos[z] sin[D] sin[H] - (cos[lat] sin[z] - sin[lat] cos[z] cos[D]) cos[H] - (sin[lat] sin[z] + cos[lat] cos[z] cos[D]) tan[delta]
x = a Nx / Q
y = a Ny / Q
return [x,y,Q]
}
drawHourAngles[g is graphics, lat, D, a, z] :=
{
deltas = [-23.44 deg, -20.15 deg, -11.47 deg, 0 deg, 11.47 deg, 20.15 deg , 23.44 deg]
Hs = new range[-45 deg, 46 deg, 15 deg]
for H = Hs
{
p = new polyline
pointFound = false
for delta = deltas
{
sunset = arccos[-tan[lat] tan[delta]]
// println["sunset is " + format[sunset, "deg", 3]]
if (H < sunset) and (H > -sunset)
{
[x,y,Q] = calculatePoint[lat, D, a, z, H, delta]
if Q > 0 // Plane illuminated?
{
pointFound = true
p.addPoint[x,-y]
}
}
}
if pointFound
{
g.add[p]
[x,y] = calculatePoint[lat, D, a, z, H, 23.55 deg]
time = round[(H/(15 degrees) * hour + 12 hours)/hour, 1]
// println["H is " + format[H, "deg", 2] + " time is $time "]
g.font["SansSerif", a/15]
g.text["$time:00", x, -y, "right", "top"]
}
}
}
/*
Calculate the "center" point of the sundial. This is not where the gnomon
is placed, but where the lines for each hour angle converge.
*/
findCenter[lat, D, a, z] :=
{
P = calcP[lat, D, a, z]
x0 = a / P cos[lat] sin[D]
y0 = -a / P (sin[lat] sin[z] + cos[lat] cos[z] cos[D])
return [x0, y0]
}
calcP[lat, D, a, z] := sin[lat] cos[z] - cos[lat] sin[z] cos[D]
// Latitude on the Earth where the sundial will be placed.
lat = 40 deg
// Alignment of the face of the sundial with respect to the compass
align = (180-22) deg // 180 deg = due south, 90 deg = due east
stylusLength = 3
// Alignment of the plane of the sundial
z = 0.1 deg // 0 deg = horizontal sundial (on floor)
// 90 deg = vertical sundial (on wall)
// Convert compass alignment to Meeus coordinates. To convert to/from
// compass coordinates, use (align + 180 deg) mod circle
alignMeeus = (align + 180 deg) mod circle
g = new graphics
drawHourAngles[g, lat, alignMeeus, stylusLength, z]
g.drawEllipseCenter[0,0,stylusLength/100, stylusLength/100]
// Draw the gnomon
g.line[-stylusLength/2, -stylusLength/10, stylusLength/2, -stylusLength/10]
g.show[]
Download or view planarSundial.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20117 days, 23 hours, 9 minutes ago.