Skip to content

Comparison with Rohr's Book

Binder

The book SUNDIALS History, Theory and Practice by Rohr (1996) is the standard reference for sundials and contains many results similar to those present here in analemma, except in various special cases, the most general of which is the case where the gnomon is a style, so its inclination \(\iota = \theta\), the (\(90^\circ\) minus) latitude angle.

In this notebook, demonstrate that our results reduce to those in Rohr when specialized to that case. Throught, we will make use of the following notational translation:

Angle analemma Rohr
Sundial declination \(d\) \(-d\)
Hour angle \(\mu\) HA
Latitude \(90^\circ - \theta\) \(\phi\)
Gnomon-subgnomon angle \(A\) \(\alpha\)
Subgnomon-noon angle \(B\) \(\beta\)

The function rohr below specializes to the case of a style, in the notation of Rohr's book.

import sympy as sp
from sympy import sin, cos, tan, cot
from sympy.abc import d, phi, mu, iota, A

from analemma.algebra import frame, util, render, result

def rohr(expr):
    return expr.subs(iota, sp.pi/2-phi).subs(d, -d).simplify()

Noon and the Line of Greatest Slope

On page 78 of Rohr's book, he derives the tangent of \(v\), the angle between two lines in the dial face; the noon line and the line of greatest slope. The latter is the vector \(m_1\), the first vector in the dial frame. We can calculate the same as

\[\tan(v) = \frac{\sin(v)}{\cos(v)} = \frac{m_2 \cdot \hat{w}_{\mu=0}}{m_1 \cdot \hat{w}_{\mu=0}}\]

where \(\hat{w}_{\mu=0}\) is introduced in The Shadow Angle Relative to Noon.

m1, m2, m3 = frame.dial()

Sn = result.shadow_bivector_explicit()
Gn = frame.dialface()
noon_shadow = result.unit_noon_shadow(Gn, Sn)

cos_v = (noon_shadow | m1).trigsimp()
sin_v = (noon_shadow | m2).trigsimp()
render.expression(r"\tan(v)", rohr((sin_v/cos_v).trigsimp()))
\[\displaystyle \begin{equation} \tan(v) = \cos{\left (i \right )} \tan{\left (d \right )} \nonumber \end{equation} \]

This matches page 77 of Rohr, right-hand column near the top.

The Shadow and the Line of Greatest Slope

On page 78, Rohr calculates \(w\), the angle between the shadow and the line of greatest slope on the dial face. The equivalent calculation here is \(\tan(w) = -y/x\) where \(x\) and \(y\) are the coordinates of the shadow and the minus sign enters because \(m_1\) points up, not down the line of greatest slope.

x, y = result.shadow_coords_xy()
tan_w = (-y/x).subs(cos(mu), cot(mu)*sin(mu))
render.expression(r"\tan(w) = \frac{y}{-x}", rohr(tan_w))
\[\displaystyle \begin{equation} \tan(w) = \frac{y}{-x} = \frac{- \sin{\left (d \right )} \cos{\left (i \right )} \cot{\left (\mu \right )} + \sin{\left (i \right )} \cos{\left (\phi \right )} + \sin{\left (\phi \right )} \cos{\left (d \right )} \cos{\left (i \right )}}{\sin{\left (d \right )} \sin{\left (\phi \right )} + \cos{\left (d \right )} \cot{\left (\mu \right )}} \nonumber \end{equation} \]

This matches the expression given for \(\tan(w)\) around the middle of the left-hand column of page 78 in Rohr's book.

The Subgnomon

Rohr proceeds to calculate the angle between the style and the substyle, which is the projection of the style onto the dial face. Here, we have a gnomon \(g\), and define the subgnomon \(b\) similarly, given by \(b = R \bar{b} \tilde{R}\) where \(R = \exp(\pi/4 \, G)\) (see analemma.algebra.result.gnomon_dialface_angle_sin for details).

gn = frame.gnomon() # on the surface frame (n-basis)
gm = util.project_vector(gn, frame.dial(), frame.base("m")) # projected onto the dial frame (m-basis)

bn = util.update_coeffs(util.rotate(gn|Gn, -sp.pi/2, Gn).trigsimp()) # n-basis
bm = util.project_vector(bn, frame.dial(), frame.base("m")) # m-basis

render.expression("b", bm)
\[\displaystyle \begin{equation} b = \left ( \sin{\left (i \right )} \cos{\left (\iota \right )} - \sin{\left (\iota \right )} \cos{\left (d \right )} \cos{\left (i \right )}\right ) \boldsymbol{m}_{1} + \sin{\left (d \right )} \sin{\left (\iota \right )} \boldsymbol{m}_{2} \nonumber \end{equation} \]

\(b\) is not a unit vector like \(g\), but has length \(\cos(A)\) where \(A\) is the angle we seek, denoted as \(\alpha\) in Rohr. Fortunately, \(1-b^2\) has a nice factorization which yields the following.

sinA = result.gnomon_dialface_angle_sin()
render.expression(r"\sin(\alpha)", rohr(sinA))
\[\displaystyle \begin{equation} \sin(\alpha) = \sin{\left (i \right )} \cos{\left (d \right )} \cos{\left (\phi \right )} + \sin{\left (\phi \right )} \cos{\left (i \right )} \nonumber \end{equation} \]

This matches Equation 7 on page 78 of Rohr's book.

The angle between the subgnomon and the noon line is called \(\beta\) by Rohr and \(B\) in analemma notation before applying the rohr function defined above. Its cosine can be calculated as a simple scalar product of two unit vectors.

unit_subgnomon = bn/cos(A)
cosB = unit_subgnomon|noon_shadow
render.expression(r"\cos(B)", cosB)
\[\displaystyle \begin{equation} \cos(B) = \frac{\sin{\left (i \right )} \cos{\left (d \right )} \cos{\left (\iota \right )} - \sin{\left (\iota \right )} \cos{\left (i \right )}}{\sqrt{- {\sin{\left (d \right )}}^{2} {\sin{\left (i \right )}}^{2} + 1} \cos{\left (A \right )}} \nonumber \end{equation} \]

To find \(\sin(B)\), we can use the fact that we know the unit bivector \(G\) that will rotate it in the plane shared by the subgnomon.

sinB = unit_subgnomon|util.rotate(noon_shadow, sp.pi/2, Gn)
render.expression(r"\sin(B)", sinB)
\[\displaystyle \begin{equation} \sin(B) = \frac{\left(\sin{\left (i \right )} \sin{\left (\iota \right )} \cos{\left (d \right )} + \cos{\left (i \right )} \cos{\left (\iota \right )}\right) \sin{\left (d \right )} \sin{\left (i \right )}}{\sqrt{- {\sin{\left (d \right )}}^{2} {\sin{\left (i \right )}}^{2} + 1} \cos{\left (A \right )}} \nonumber \end{equation} \]

The inelegant denominator cancels in the ratio. Moving to Rohr's notation, we have a formula that matches the expression at the bottom of the right-hand column of page 78.

tanB = (sinB/cosB).subs(sin(iota), tan(iota)*cos(iota))
render.expression( r"\tan(\beta)", rohr(tanB))
\[\displaystyle \begin{equation} \tan(\beta) = - \frac{\left(\sin{\left (i \right )} \cos{\left (d \right )} + \cos{\left (i \right )} \tan{\left (\phi \right )}\right) \sin{\left (d \right )} \sin{\left (i \right )}}{\sin{\left (i \right )} \cos{\left (d \right )} \tan{\left (\phi \right )} - \cos{\left (i \right )}} \nonumber \end{equation} \]