# planarSundial.frink

``` // 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[-60 deg, 61 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, "center", "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 = (270-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[] ```

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 19093 days, 18 hours, 43 minutes ago.