# 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[] ```