In the previous post we used Clojure to manipulate the matrix definition of a simple rate, time, and distance nomogram, one suitable for a long road trip. After a little beta testing with the kids, it turns out they're less interested in academic questions like how many hours until the next state or how many more miles today than they are in more practical matters like when we'll stop for a bathroom break. The original nomogram omitted times less than an hour, so in this post we'll make a new nomogram that zooms in on the smaller time ranges.
Here's the base nomographic matrix we worked out:
(-> rate-time-distance (add-column-to-column 1 2) (divide-row-by 2 2) (swap-columns 0 1) simplify)
[[0 (log r) 1] [1 (log t) 1] [1/2 (/ (log d) 2) 1]]
We're using logarithmic scales, so we can't show zero hours of travel as it would put the end of the scale at negative infinity. Instead, we'll pick two minutes as a reasonable lower limit. Plotting the above nomogram for a time range of two minutes to three hours gives us this:
Not an efficient use of available space. Fortunately, all the scales are about the same size, so we can use a vertical shear to realign them:
(defn shear-y [matrix s] (mapv (fn [[x y z]] `[~x (+ ~y (* ~x ~s)) ~z]) matrix))
Note that this shear operation differs slightly from Doerfler's, which alters both the x- and y-axes using a rotation. In practice, leaving the x-axis unchanged doesn't seem to affect results, so I've followed Doerfler's example from later in the post, where he shears the x-axis but keeps the y-axis as is.
To align the time scale's lower end with the lower end of the speed scale, we need to shear it upward by however far it extends below y = 0. Since log(2 minutes) = log(2/60 hour) ≈ -1.48, we need to shear the right scale up by about 1.5 units. The actual amount of y-shear depends on the scale's x-position, but in this case the math is easy, as the time scale has an x-coordinate of 1.
(-> rate-time-distance (add-column-to-column 1 2) (divide-row-by 2 2) (swap-columns 0 1) (shear-y (- (Math/log10 2/60))) simplify)
[[0 (+ (log r) 0.0) 1] [1 (+ (log t) 1.4771212547196624) 1] [1/2 (+ (/ (log d) 2) 0.7385606273598312) 1]]