Jekyll2024-02-06T02:05:49+00:00https://brsr.github.io/feed.xmlThe BRSR BlogBRSR's personal blogSpherical area coordinates, and a derived triangle center2023-11-04T00:00:00+00:002023-11-04T00:00:00+00:00https://brsr.github.io/2023/11/04/spherical-areal<p><a href="/2023/07/29/spherical-trilinear-barycentric.html">An earlier post</a> explained homogenous coordinates on the sphere, and derived some relationships between spherical triangle centers. A certain geometric property of Euclidean barycentric coordinates fails to carry over into spherical geometry. Specifically, the Euclidean barycentric coordinate \(\beta_i\) equals the ratio of the area of the small triangle opposite vertex \(i\) and the area of the large triangle: this remains true for points outside the triangle if signed areas are used. The previous is not true for spherical homogenous coordinates, but an analogous set of coordinates will be defined below.</p>
<p>Russell<sup id="fnref:Russell" role="doc-noteref"><a href="#fn:Russell" class="footnote" rel="footnote">1</a></sup> notes that in spherical geometry, the point where the medians of the triangle intersect is in general not the same as the point that divides a triangle into three smaller triangles of equal area as shown. He gives a formula for the vertex median point: \((\csc A : \csc B : \csc C)\), but not the equal-area center. Later, we use spherical area coordinates to derive that center and some related points.</p>
<p>We’ll switch between notation using angles labeled \(A\), \(B\), and \(C\) and vertices labeled with subscripts \(i\), depending on which is more convenient. The length of the edge opposite is \(a\), \(b\), or \(c\); or \(\ell_i\), correspondingly.</p>
<h1 id="spherical-area-coordinates">Spherical area coordinates</h1>
<p>Let \(\hat{\mathbf v}_i\) be the vertices of the triangle and \(\hat{\mathbf v}_P\) be the projected point. Let \(\Omega_i\) designate the signed geodesic area of the small triangle opposite of vertex \(i\), and \(\Omega\) designate the area of the large triangle. Area coordinates on the sphere can be defined as:</p>
\[\alpha_i = \frac{\Omega_i}{\Omega}\]
<p>These coordinates can be applied to any surface where area is well-defined. On the sphere, the area of a triangle can calculated from the total of the interior angles minus \(\pi\), although that is an unsigned quantity, and often calculating each angle is numerically unstable. A formula such as this may be used instead:</p>
\[\tan \left( \frac{\Omega}{2} \right) = \frac{|\mathbf{\hat{v}_1} \cdot
\mathbf{\hat{v}}_2 \times \mathbf{\hat{v}}_3|}
{1+\mathbf{\hat{v}}_1\cdot \mathbf{\hat{v}}_2+\mathbf{\hat{v}}_2
\cdot \mathbf{\hat{v}}_3+\mathbf{\hat{v}}_3\cdot \mathbf{\hat{v}}_1}\]
<p>For points within the triangle, \(\alpha_i\) are all positive. Outside, some may be negative. In particular, in the triangle formed by the antipodes of \(\hat{\mathbf v}_i\), all of \(\alpha_i\) are negative. Except for in that antipodal triangle, \(\sum \alpha_i = 1\).</p>
<h1 id="inverse">Inverse</h1>
<p>The idea of spherical area coordinates presented above is not new: for example, Praun et al.,<sup id="fnref:Praun" role="doc-noteref"><a href="#fn:Praun" class="footnote" rel="footnote">2</a></sup> Carfora et al.,<sup id="fnref:Carfora" role="doc-noteref"><a href="#fn:Carfora" class="footnote" rel="footnote">3</a></sup> and Lei et al.<sup id="fnref:Lei" role="doc-noteref"><a href="#fn:Lei" class="footnote" rel="footnote">4</a></sup> have written about it before. The latter article includes an formula to convert \(\alpha_i\) back to \(\hat{\mathbf v}_P\), given in terms of a matrix that must be inverted. However, in a math.StackExchange post,<sup id="fnref:Hui" role="doc-noteref"><a href="#fn:Hui" class="footnote" rel="footnote">5</a></sup> Achille Hui gives a close-formula for this inverse. I repeat it here in preparation for whenever StackExchange finally bites the dust. There are some quantities that depend only on the larger triangle, not the point to be projected:</p>
\[\begin{split}
k_i & = \mathbf v_{i-1} \cdot \mathbf v_{i+1} = \cos \ell_i\\
h_i & = \frac{k_{i-1} + k_{i+1}}{1 + k_i}\\
\tau &= \tan\left(\frac{\Omega}{2}\right) \\
\end{split}\]
<p>With that, consider \(\alpha_i\) as givens, and proceed as follows. While lengthy, this set of formulas consists only of scalar and vector arithmetical operations and the \(\tan\) function.</p>
\[\begin{split}
\Omega_i &= \alpha_i \Omega \\
\tau_i &= \tan\left(\frac{\Omega_i}{2}\right) \\
t_i &= \frac{\tau_i}{\tau} \\
g_i &= \frac{t_i}{(1+h_i) + (1-h_i) t_i} = \frac{\tau_i}{(1+h_i) \tau + (1-h_i) \tau_i} \\
f_i &= \frac{g_i}{1 - g_1 - g_2 - g_3} \\
\hat{\mathbf v}_P &= \sum^3_{i=1} f_i \hat{\mathbf v}_i = \frac{\sum^3_{i=1} g_i \hat{\mathbf v}_i }{ 1 - \sum^3_{i=1} g_i }
\end{split}\]
<p>Note that the final formula is a linear combination of vectors, as appears in Euclidean barycentric coordinates.</p>
<h1 id="small-triangles">Small triangles</h1>
<p>It is easy to demonstrate that for small triangles, and for points within or near the triangle, spherical areal coordinates are approximately barycentric coordinates. Remember that \(\sum \alpha_i = 1\) except within the antipodal triangle, which is far enough away that we’re not concerned with it.</p>
\[\begin{split}
k_i &= \cos \ell_i \approx 1 \\
h_i &= \frac{k_{i-1} + k_{i+1}}{1 + k_i} \approx 1 \\
\tau &= \tan\left(\frac{\Omega}{2}\right) \approx \frac{\Omega}{2}\\
\tau_i &= \tan\left(\frac{\Omega_i}{2}\right) \approx \frac{\Omega_i}{2} = \alpha_i \frac{\Omega}{2}\\
t_i &= \frac{\tau_i}{\tau} \approx \alpha_i\\
g_i &= \frac{t_i}{(1+h_i) + (1-h_i) t_i} \approx \frac{t_i}{2} = \frac{\alpha_i}{2}\\
f_i &= \frac{g_i}{1 - g_1 - g_2 - g_3} \approx \frac{\alpha_i/2}{1 - \alpha_1/2 - \alpha_2/2 - \alpha_3/2} = \frac{\alpha_i}{2 - \alpha_1 - \alpha_2 - \alpha_3} = \alpha_i \\
\mathbf v_P &= \sum^3_{i=1} f_i \mathbf v_i \approx \sum^3_{i=1} \alpha_i \mathbf v_i
\end{split}\]
<h1 id="specific-points">Specific points</h1>
<h2 id="center">Center</h2>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/areacenter/area_center_10-90-90.svg" title=".">
<img src="/assets/images/areacenter/area_center_10-90-90.svg" title="." alt="." />
<span>.</span>
</a></li>
<li><a href="/assets/images/areacenter/area_center_40-34-129.svg" title=".">
<img src="/assets/images/areacenter/area_center_40-34-129.svg" title="." alt="." />
<span>.</span>
</a></li>
<li><a href="/assets/images/areacenter/area_center_56-133-18.svg" title=".">
<img src="/assets/images/areacenter/area_center_56-133-18.svg" title="." alt="." />
<span>.</span>
</a></li>
<li><a href="/assets/images/areacenter/area_center_158-60-44.svg" title=".">
<img src="/assets/images/areacenter/area_center_158-60-44.svg" title="." alt="." />
<span>.</span>
</a></li>
<li><a href="/assets/images/areacenter/area_center_162-49-52.svg" title=".">
<img src="/assets/images/areacenter/area_center_162-49-52.svg" title="." alt="." />
<span>.</span>
</a></li>
<li><a href="/assets/images/areacenter/area_center_171-167-174.svg" title=".">
<img src="/assets/images/areacenter/area_center_171-167-174.svg" title="." alt="." />
<span>.</span>
</a></li>
</ul>
<p>Several examples of the equal-area center of a triangle are shown above: these (and more random triangles that I’m not showing because they basically look like these or they’re close to being equilateral) have been numerically verified to divide the triangle into three triangles of equal area. Define \(S = \frac{A+B+C}{2}\), and \(\Omega = 2S - \pi\), which is the spherical area of the triangle. In homogenous coordinates, the equal-area triangle center is</p>
\[\csc \left( A - \frac{\Omega}{3}\right) : \csc \left( B - \frac{\Omega}{3}\right) : \csc \left( C - \frac{\Omega}{3}\right)\]
<p>This is probably also the equal-area center for hyperbolic geometry, but I haven’t verified that and there might be a sign change somewhere.</p>
<p>This can be derived from the inverse formula using \(\alpha_1 = \alpha_2 = \alpha_3 = 1/3\) and converting all the lengths that appear to angles. Or in long-form:</p>
<h3 id="derivation">Derivation</h3>
<p>We start with a derivation of the barycentric coordiantes for this center. The derivation is simplified in two ways. One is that, since barycentric coordinates are homogenous, we can ignore the denominator of \(f_i\), which is invariant under permutation of indices, and concentrate on \(g_i\) instead. The other is that we can just focus on \(g_1\) and get \(g_2\) and \(g_3\) by symmetry once we’re finished.</p>
<p>Note that \(\tau = \tan\left(\frac{\Omega}{2}\right)\) and, given the values for \(\alpha_i\) above, \(\tau_i = \tan\left(\frac{\Omega}{6}\right)\) regardless of \(i\). We’ll actually need \(t_1^{-1}\), which, with the appropriate <strike>computer algebra system</strike>trig identities, simplifies as:</p>
\[t_1^{-1} = \frac{\tau}{\tau_i} = \frac{\tan\left(\frac{\Omega}{2}\right)}{\tan\left(\frac{\Omega}{6}\right)}
= \frac{2}{2 \cos\left(\frac{\Omega}{3}\right) - 1} + 1\]
<p>It winds up being more convenient for the derivation to rearrange \(g_1\) slightly, and then substitute \(t_1\).</p>
\[\begin{split}
g_1 &= \frac{t_1}{(1+h_1) + (1-h_1) t_1} \\
& = \left(\frac{1+h_1}{t_1} + 1-h_1 \right)^{-1} \\
& = \left(\left(1+h_1\right)\left(\frac{2}{2 \cos\left(\frac{\Omega}{3}\right) - 1} + 1\right) + 1-h_1 \right)^{-1} \\
& = \left(2\frac{1+h_1}{2 \cos\left(\frac{\Omega}{3}\right) - 1} + 2 \right)^{-1}
\end{split}\]
<p>At this point we examine the quantity \(1+h_1\):</p>
\[1 + h_1 = \frac{k_3 + k_2}{1 + k_1} + 1 = \frac{1 + k_1 + k_2 + k_3}{1 + k_1}
= \frac{1 + \cos a + \cos b + \cos c}{1 + \cos a}\]
<p>For reference, the <a href="https://en.wikipedia.org/wiki/Spherical_law_of_cosines">spherical law of cosines for angles</a> can be rearranged to isolate the length:</p>
\[\cos c = \frac{\cos A \cos B + \cos C}{\sin A \sin B}\]
<p>and correspondingly for lengths \(a\) and \(b\). Substitute the denominator first to get a feel for the problem:</p>
\[\begin{split}
1 + \cos a &= 1 + \frac{\cos B \cos C + \cos A}{\sin B \sin C} \\
&= \frac{\sin B \sin C + \cos B \cos C + \cos A}{\sin B \sin C} \\
&= 2 \frac{\cos \frac{A-B+C}{2} \cos \frac{A+B-C}{2}}{\sin B \sin C} \\
&= 2 \frac{\cos \left(S - B \right) \cos \left(S - C \right)}{\sin B \sin C}
\end{split}\]
<p>where \(S\) was defined earlier. Now for the numerator. Ideally, we’ll want some factors in common so we can simplify the rational expression. Also note that the original expression was invariant under cyclic permutation of the triangle, so whatever we come up with at the end should be too.</p>
\[\begin{split}
&1 + \cos a + \cos b + \cos c \\
&= 1 + \frac{\cos B \cos C + \cos A}{\sin B \sin C} + \frac{\cos C \cos A + \cos B}{\sin C \sin A} + \frac{\cos A \cos B + \cos C}{\sin A \sin B} \\
&= \frac{\sin A \sin B \sin C + \sin A \cos B \cos C + \cos A \sin A + \cos A \sin B \cos C + \cos B \sin B + \cos A \cos B \sin C + \cos C \sin C}{\sin A \sin B \sin C} \\
&= \frac{4 \sin(A/2 + B/2 + C/2) \cos(A/2 - B/2 - C/2) \cos(A/2 + B/2 - C/2) \cos(A/2 - B/2 + C/2)}{\sin A \sin B \sin C} \\
&= 4 \frac{\sin(S) \cos(S-A) \cos(S-B) \cos(S-C)}{\sin A \sin B \sin C}
\end{split}\]
<p>Therefore,</p>
\[\begin{split}
1 + h_1 &= \frac{1 + \cos a + \cos b + \cos c}{1 + \cos a} \\
&= 4 \frac{\sin(S) \cos(S-A) \cos(S-B) \cos(S-C)}{\sin A \sin B \sin C} \cdot \frac{\sin B \sin C}{2 \cos \left(S - B \right) \cos \left(S - C \right)} \\
&= 2 \frac{\sin(S) \cos\left(S-A\right)}{\sin A} \\
&= 2 \frac{\cos\frac{\Omega}{2} \sin\left(A-\frac{\Omega}{2}\right)}{\sin A}
\end{split}\]
<p>In preparation for the next step, the last equality substitutes \(S = \frac{\Omega+\pi}{2}\). Now plug \(1 + h_1\) into the expression of \(g_1\) from earlier.</p>
\[\begin{split}
g_1 &= \left(2\frac{1+h_1}{2 \cos\left(\frac{\Omega}{3}\right) - 1} + 2 \right)^{-1} \\
&= \left(4\frac{\cos\frac{\Omega}{2} \sin\left(A-\frac{\Omega}{2}\right)}{\sin A \left(2 \cos\left(\frac{\Omega}{3}\right) - 1 \right)} + 2 \right)^{-1} \\
&= \frac{\sin A}{4\frac{\cos\frac{\Omega}{2} \sin\left(A-\frac{\Omega}{2}\right)}{\left(2 \cos\left(\frac{\Omega}{3}\right) - 1 \right)} + 2\sin A} \\
&= \frac{\sin A}{4 \cos\frac{\Omega}{6} \sin\left(A-\frac{\Omega}{2}\right) + 2\sin A} \\
&= \frac{\sin A}{2 \left(2 \cos\left(\frac{\Omega}{3}\right) + 1\right) \sin\left(A - \frac{\Omega}{3}\right)}
\end{split}\]
<p>Finally, note that the term \(2 \left(2 \cos\left(\frac{\Omega}{3}\right) + 1\right)\) is invariant under cyclic permutation of the triangle. Since we are working with homogenous coordinates, that term can be ignored. The barycentric coordinates of the area center are:</p>
\[\frac{\sin A}{\sin\left(A - \frac{\Omega}{3}\right)} : \frac{\sin B}{\sin\left(B - \frac{\Omega}{3}\right)} : \frac{\sin C}{\sin\left(C - \frac{\Omega}{3}\right)}\]
<p>To convert to trimetric coordinates, divide the first term by \(\sin a\), the second by \(\sin b\), and the third by \(\sin c\). By the spherical law of sines,</p>
\[\frac{\sin A}{\sin a} = \frac{\sin B}{\sin b} = \frac{\sin C}{\sin c}\]
<p>so that’s another constant multiplier we can drop. The trimetric coordinates are therefore</p>
\[\frac{1}{\sin\left(A - \frac{\Omega}{3}\right)} : \frac{1}{\sin\left(B - \frac{\Omega}{3}\right)} : \frac{1}{\sin\left(C - \frac{\Omega}{3}\right)}\]
<p>which can be more succinctly expressed using cosecant, as written earlier.</p>
<h3 id="sanity-check">Sanity check</h3>
<p>This derivation is somewhat opaque, and doesn’t really give any geometric insight. Let’s make a sanity check: we would expect the equal-area center to always be inside the triangle. Thus, all the components of the coordinates should be positive, possibly zero for degenerate triangles. Here’s a proof of that.</p>
<p>First, assume that the triangle is proper, such that \(0 \le A \le \pi\) and similarly for \(B\) and \(C\).</p>
<p>Note that the triangle is contained within the spherical lune created by extending the edges opposite \(B\) and \(C\) to their other point of intersection. The angle of intersection at either point is \(A\), and the area of the lune is \(2A\). Therefore, \(\Omega \le 2A\). Substitute the inequality into the first coordinate: \(A - \frac{\Omega}{3} \ge A - \frac{2}{3}A = \frac{1}{3}A \ge 0\), where the rightmost inequality is the lower bound of the initial assumption.</p>
<p>On the other end,</p>
\[A - \frac{\Omega}{3} = A - \frac{A + B + C - \pi}{3} = \frac{2}{3}A - \frac{B + C - \pi}{3} \le \frac{2}{3}\pi - \frac{B + C - \pi}{3}
= \pi - \frac{B + C}{3} \le \pi\]
<p>where the final inequality applies the lower bound of the initial assumption, i.e. that B and C are nonnegative.</p>
<p>Therefore, \(0 \le A - \frac{\Omega}{3} \le \pi\). \(\csc\) is positive over that range of inputs. The same argument applies to the second and third coordinates. QED.</p>
<h2 id="edge-midpoints">Edge midpoints</h2>
<p>The point on the edge opposite angle \(C\) such that the edge from that point to \(c\) bisects the triangle into two equal-area parts is:</p>
\[\csc \left( A - \frac{\Omega}{4}\right) : \csc \left( B - \frac{\Omega}{4}\right) : 0\]
<p>Expressions for the other edges are analogous. This can be derived using area coordinates too, although i’m sure there’s a clever geometric proof. Let \(\alpha_1 = \alpha_2 = 1/2\) and \(\alpha_3 = 0\). \(1+h_1\) is the same as before:</p>
\[\begin{split}
1 + h_1 = 2 \frac{\cos\frac{\Omega}{2} \sin\left(A-\frac{\Omega}{2}\right)}{\sin A}
\end{split}\]
\[t_1^{-1} = \frac{\tau}{\tau_1} = \frac{\tan\left(\frac{\Omega}{2}\right)}{\tan\left(\frac{\Omega}{4}\right)}
= \sec\frac{\Omega}{2} + 1\]
\[\begin{split}
g_1 &= \left(\frac{1+h_1}{t_1} + 1-h_1 \right)^{-1} \\
&= \left(\left(1+h_1\right)\left( \sec\frac{\Omega}{2} + 1\right) + 1-h_1 \right)^{-1} \\
&= \left(\frac{1+h_1}{\cos \frac{\Omega}{2} } + 2 \right)^{-1} \\
&= \left(2\frac{\cos\frac{\Omega}{2} \sin\left(A-\frac{\Omega}{2}\right)}{\sin A \cos \frac{\Omega}{2} } + 2 \right)^{-1} \\
&= \left(2\frac{\sin\left(A-\frac{\Omega}{2}\right)}{\sin A} + 2 \right)^{-1} \\
&= \frac{\sin A}{2 \sin\left(A-\frac{\Omega}{2}\right) + 2\sin A} \\
&= \frac{\sin A}{4 \cos \frac{\Omega}{2} \sin\left(A-\frac{\Omega}{4}\right)}
\end{split}\]
<p>As before, we can ignore the factor \(4 \cos \frac{\Omega}{2}\). The second coordinate can be found by analogy, and the third can be easily shown to be 0, leading to the expression given above.</p>
<p>Note that these are not the points that can be used to divide a spherical triangle into six smaller triangles, but that can be accomplished by dividing a spherical triangle into three triangles using the equal-area center, and then dividing those triangles in two using the midpoint opposite the equal-area center.</p>
<p><em>A Python script to create the figures in this post is located <a href="https://github.com/brsr/mapproj/blob/master/bin/equalareapoint.py">here</a>.</em></p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:Russell" role="doc-endnote">
<p>Russell, Robert A. (2016), “Non-Euclidean Triangle Centers”, arXiv preprint, arXiv:1608.08190, <a href="https://arxiv.org/abs/1608.08190">https://arxiv.org/abs/1608.08190</a> <a href="#fnref:Russell" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Praun" role="doc-endnote">
<p>Praun, Emil; Hoppe, Hugues (2003), “Spherical parametrization and remeshing”, ACM Transactions on Graphics, 22 (3): 340–349, doi:10.1145/882262.882274, <a href="http://hhoppe.com/sphereparam.pdf">http://hhoppe.com/sphereparam.pdf</a> <a href="#fnref:Praun" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Carfora" role="doc-endnote">
<p>Carfora, Maria Francesca (2007), “Interpolation on spherical geodesic grids: A comparative study”, Journal of Computational and Applied Mathematics, 210 (1–2): 99–105, doi:10.1016/j.cam.2006.10.068, <a href="https://www.sciencedirect.com/science/article/pii/S0377042706006522">https://www.sciencedirect.com/science/article/pii/S0377042706006522</a> <a href="#fnref:Carfora" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Lei" role="doc-endnote">
<p>Lei, Kin; Qi, Dongxu; Tian, Xiaolin (2020), “A new coordinate system for constructing spherical grid systems”, Applied Sciences, 10 (2): 655, doi:10.3390/app10020655, <a href="https://www.mdpi.com/2076-3417/10/2/655/htm">https://www.mdpi.com/2076-3417/10/2/655/htm</a> <a href="#fnref:Lei" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Hui" role="doc-endnote">
<p>Hui, Achille (2019), <a href="https://math.stackexchange.com/questions/1151428/point-within-a-spherical-triangle-given-areas/1244218">https://math.stackexchange.com/questions/1151428/point-within-a-spherical-triangle-given-areas/1244218</a> <a href="#fnref:Hui" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>An earlier post explained homogenous coordinates on the sphere, and derived some relationships between spherical triangle centers. A certain geometric property of Euclidean barycentric coordinates fails to carry over into spherical geometry. Specifically, the Euclidean barycentric coordinate \(\beta_i\) equals the ratio of the area of the small triangle opposite vertex \(i\) and the area of the large triangle: this remains true for points outside the triangle if signed areas are used. The previous is not true for spherical homogenous coordinates, but an analogous set of coordinates will be defined below.Homogeneous coordinates on the sphere with vectors2023-07-29T00:00:00+00:002023-07-29T00:00:00+00:00https://brsr.github.io/2023/07/29/spherical-trilinear-barycentric<p><a href="https://en.wikipedia.org/wiki/Trilinear_coordinates">Trilinear coordinates</a>, a type of <a href="https://en.wikipedia.org/wiki/Homogeneous_coordinates">homogeneous coordinate</a>, are very useful for the study of Euclidean triangles, especially that of triangle centers. They can be specified as a triplet of coordinates, \((x: y: z)\). Colons are used instead of commas to emphasize that these quantities are ratios: \((x: y: z)\) is the same point as \((kx: ky: kz)\) for any positive constant \(k\). The values x, y, and z are the perpendicular directed distance between the specified point and each side of a given triangle.</p>
<p>homogeneous coordinates can also be defined for the sphere (also hyperbolic space, but we’re not interested in that right now). The coordinates are in proportion to the sines of the distances instead: \((\sin x: \sin y: \sin z)\). <a href="https://arxiv.org/abs/1608.08190">Spherical triangle centers can be defined like in the Euclidean case.</a></p>
<p>In this post, I derive how to convert these coordinates to and from vectors on the unit sphere. Let the vertices of this triangle be \(\mathbf{\hat{a}}\), \(\mathbf{\hat{b}}\), and \(\mathbf{\hat{c}}\), arranged in counterclockwise order. As is standard in the study of triangle centers, let \(A\), \(B\), \(C\) be the interior angles at each vertex, and \(a\), \(b\), \(c\) be the length of the edge opposite each vertex. Note that \(\| \mathbf{\hat{a}} \times \mathbf{\hat{b}} \| = \sin c\) and \(\mathbf{\hat{a}} \cdot \mathbf{\hat{b}} = \cos c\), and so on for the other edges. Also let \(\mathbf{\hat{p}}\) be some other point on the sphere, and \((f, g, h) = \mathbf{h}\) be the homogeneous coordinates of that point.</p>
<h1 id="trilinear">Trilinear</h1>
<p>The great circle center corresponding to the edge between \(\mathbf{\hat{a}}\) and \(\mathbf{\hat{b}}\), also called (at least in the context of spherical triangles) the pole of \(\mathbf{\hat{c}}\), is</p>
\[\mathbf{\hat{c}}' =
\frac{\mathbf{\hat{a}} \times \mathbf{\hat{b}}
}{\| \mathbf{\hat{a}} \times \mathbf{\hat{b}} \|}
=
\frac{\mathbf{\hat{a}} \times \mathbf{\hat{b}}
}{\sin c}\]
<p>The distance between \(\mathbf{\hat{p}}\) and \(\mathbf{\hat{c}}'\) is therefore \(\cos z' = \mathbf{\hat{p}} \cdot \mathbf{\hat{c}}'\). Being a great circle, \(\mathbf{\hat{c}}'\) has a distance of \(\pi/2\) to \(\mathbf{\hat{a}}\), \(\mathbf{\hat{b}}\), and any other point on that great circle. Therefore the perpendicular distance between \(\mathbf{\hat{p}}\) and that great circle is \(z = \pi/2 - z'\), and it also follows that</p>
\[\sin z = \mathbf{\hat{p}} \cdot \mathbf{\hat{c}}'\]
<p>where \(\sin z\) is one of the coordinates. The other two can be found by cyclic permutation of the vertices. All these may be combined in matrix form as</p>
\[\begin{bmatrix}
\mathbf{\hat{a}}' \\ \mathbf{\hat{b}}' \\ \mathbf{\hat{c}}'
\end{bmatrix} \mathbf{\hat{p}} = \begin{bmatrix}
\sin x \\
\sin y \\
\sin z
\end{bmatrix}
= \mathbf{h}\]
<p>which can be easily inverted:</p>
\[\begin{bmatrix}
\mathbf{\hat{a}} \sin a
& \mathbf{\hat{b}} \sin b
& \mathbf{\hat{c}} \sin c
\end{bmatrix} \mathbf{h} = \mathbf{p}\]
<p>Note that we don’t really need to calculate \(x, y, z\), just their sines. Also note that some factors are dropped from the inverted formula, or I should rather say they are absorbed into \(\mathbf{h}\) or \(\mathbf{p}\). The last formula determines \(\mathbf{p}\), not \(\mathbf{\hat{p}}\), which can be calculated as \(\mathbf{\hat{p}} = \frac{\mathbf{p}}{\|\mathbf{p}\|}\)</p>
<h1 id="barycentric-coordinates">Barycentric coordinates</h1>
<p>If \((f, g, h)\) are trilinear coordinates, the corresponding barycentric coordinates are \(\mathbf{\beta} = (f a, g b, h c)\). If \((f, g, h)\) are homogeneous coordinates on the sphere, the corresponding spherical barycentric coordinates are \(\mathbf{\beta} = (f \sin a, g \sin b, h \sin c)\). Notably, the sines of the edges cancel out the factors in the matrix equations above. The spherical barycentric coordinates \(\mathbf{\beta}\) relate to the point \(\mathbf{p}\) as:</p>
\[\begin{bmatrix}
\mathbf{\hat{b}} \times \mathbf{\hat{c}} \\
\mathbf{\hat{c}} \times \mathbf{\hat{a}} \\
\mathbf{\hat{a}} \times \mathbf{\hat{b}}
\end{bmatrix} \mathbf{\hat{p}}
= \mathbf{\beta}\]
<p>and</p>
\[\begin{bmatrix}
\mathbf{\hat{a}}
& \mathbf{\hat{b}}
& \mathbf{\hat{c}}
\end{bmatrix} \mathbf{\beta} = \mathbf{p}\]
<p>These are the same equations to relate a point in Euclidean space with its barycentric coordinates, although the spherical barycentric coordinates don’t share all the geometric properties of Euclidean barycentric coordinates.</p>
<p><a href="/2021/06/12/perspective-vector.html">An earlier post</a> discussed how to express the gnomonic projection using barycentric coordinates. The gnomonic projection can be thought of as calculating barycentric coordinates on the sphere, then using them as barycentric coordinates in the plane, or vice versa.</p>
<h1 id="polar-triangle">Polar triangle</h1>
<p>A bit of a detour before we get to triangle centers. Let
\(\mathbf{\hat{a}} = \frac{\mathbf{\hat{e}} \times \mathbf{\hat{f}}}{\ldots}\),
\(\mathbf{\hat{b}} = \frac{\mathbf{\hat{f}} \times \mathbf{\hat{d}}}{\ldots}\), and
\(\mathbf{\hat{c}} = \frac{\mathbf{\hat{d}} \times \mathbf{\hat{e}}}{\ldots}\), so that abc is the polar triangle of def. def is also the polar triangle of abc:</p>
\[\frac{\mathbf{\hat{a}} \times \mathbf{\hat{b}}}{\ldots}
= \frac{(\mathbf{\hat{e}} \times \mathbf{\hat{f}}) \times (\mathbf{\hat{f}} \times \mathbf{\hat{d}})}{\ldots}
= \frac{\begin{bmatrix}\mathbf{\hat{e}} & \mathbf{\hat{f}} & \mathbf{\hat{d}}\end{bmatrix} \mathbf{\hat{f}}}{\ldots}
= \frac{\mathbf{\hat{f}}}{\ldots}
= \mathbf{\hat{f}}\]
<p>By the properties of the polar triangle,</p>
\[A = \pi - d,
B = \pi - e,
C = \pi - f,
a = \pi - D,
b = \pi - E,
c = \pi - F,\]
<p>and note that \(\sin (\pi - x) = \sin x\) and \(\cos (\pi - x) = -\cos x\).</p>
<p>Note that by the spherical law of sines,</p>
\[\frac{\sin A}{\sin a} = \frac{\sin B}{\sin b} = \frac{\sin C}{\sin c}
= \frac{\begin{bmatrix}\mathbf{\hat{e}} & \mathbf{\hat{f}} & \mathbf{\hat{d}}\end{bmatrix}}{\sin a\sin b\sin c}.\]
<p>If triangle abc is the polar triangle of def, the transformations can be expressed as:</p>
\[\begin{bmatrix}
\mathbf{\hat{d}} \\ \mathbf{\hat{e}} \\ \mathbf{\hat{f}}
\end{bmatrix} \mathbf{\hat{p}}
= \mathbf{h}\]
<p>and</p>
\[\begin{bmatrix}
\mathbf{\hat{e}} \times \mathbf{\hat{f}} &
\mathbf{\hat{f}} \times \mathbf{\hat{d}} &
\mathbf{\hat{d}} \times \mathbf{\hat{e}}
\end{bmatrix} \mathbf{h} = \mathbf{p}.\]
<p>We can convert trilinear coordinates on a triangle abc to trilinear coordinates on its polar triangle through a composition of transformations:
\(\begin{bmatrix}
\mathbf{\hat{a}} \\ \mathbf{\hat{b}} \\ \mathbf{\hat{c}}
\end{bmatrix}
\begin{bmatrix}
\mathbf{\hat{a}} \sin a
& \mathbf{\hat{b}} \sin b
& \mathbf{\hat{c}} \sin c
\end{bmatrix}
\mathbf{h}
= \mathbf{h}'\)</p>
<p>Writing out the inner matrix explicitly,
\(\begin{bmatrix}
\mathbf{\hat{a}} \\ \mathbf{\hat{b}} \\ \mathbf{\hat{c}}
\end{bmatrix}
\begin{bmatrix}
\mathbf{\hat{a}} \sin a
& \mathbf{\hat{b}} \sin b
& \mathbf{\hat{c}} \sin c
\end{bmatrix}
=
\begin{bmatrix}
\mathbf{\hat{a}} \cdot \mathbf{\hat{a}} \sin a & \mathbf{\hat{a}} \cdot \mathbf{\hat{b}} \sin b & \mathbf{\hat{a}} \cdot \mathbf{\hat{c}} \sin c \\
\mathbf{\hat{b}} \cdot \mathbf{\hat{a}} \sin a & \mathbf{\hat{b}} \cdot \mathbf{\hat{b}} \sin b & \mathbf{\hat{b}} \cdot \mathbf{\hat{c}} \sin c \\
\mathbf{\hat{c}} \cdot \mathbf{\hat{a}} \sin a & \mathbf{\hat{c}} \cdot \mathbf{\hat{b}} \sin b & \mathbf{\hat{c}} \cdot \mathbf{\hat{c}} \sin c
\end{bmatrix}
=
\begin{bmatrix}
\sin a & \cos c \sin b & \cos b \sin c \\
\cos c \sin a & \sin b & \cos a \sin c \\
\cos b \sin a & \cos a \sin b & \sin c
\end{bmatrix}\)</p>
<p>The inverse matrix is the same with the distances replaced by the corresponding angles (\(A\) for \(a\), etc.)</p>
<h1 id="triangle-centers">Triangle centers</h1>
<p><a href="/2021/05/02/spherical-triangle-centers.html">An earlier post described some triangle centers in terms of vectors, derived in terms of their geometric properties.</a> Here we illustrate that the homogenous coordinates in the article i need to reference here correspond to the same vector formulas. For simplicity, the denominators in these formulas are omitted.</p>
<h2 id="incenter">Incenter</h2>
\[\mathbf{h} = (1: 1: 1)\]
\[\mathbf{p} = \mathbf{\hat{a}} \sin a + \mathbf{\hat{b}} \sin b + \mathbf{\hat{c}} \sin c
= \mathbf{\hat{a}} \| \mathbf{\hat{b}} \times \mathbf{\hat{c}} \|
+ \mathbf{\hat{b}} \| \mathbf{\hat{c}} \times \mathbf{\hat{a}} \|
+ \mathbf{\hat{c}} \| \mathbf{\hat{a}} \times \mathbf{\hat{b}} \|\]
<p>as given in the earlier post.</p>
<h2 id="vertex-median-point-centroid">Vertex-Median point (Centroid)</h2>
\[\mathbf{h} = (\csc A: \csc B: \csc C)\]
\[\mathbf{p} = \mathbf{\hat{a}} \frac{\sin a}{\sin A}
+ \mathbf{\hat{b}} \frac{\sin b}{\sin B}
+ \mathbf{\hat{c}} \frac{\sin c}{\sin C}\]
<p>By the spherical law of sines, \(\frac{\sin a}{\sin A} = \frac{\sin b}{\sin B} = \frac{\sin c}{\sin C}\), so we can factor out those terms. Somewhat abusing notation by absorbing the constant into \(\mathbf{p}\), we find that</p>
\[\mathbf{p} = \mathbf{\hat{a}} + \mathbf{\hat{b}} + \mathbf{\hat{c}}\]
<p>as given in the earlier post.</p>
<h2 id="circumcenter">Circumcenter</h2>
<p>\(\mathbf{h} = (\sin(S - A) : \sin(S - B) : \sin(S - C))\)</p>
<p>where \(S = (A + B + C)/2\)</p>
\[\mathbf{p} = \mathbf{\hat{a}} \sin a \sin(S - A) + \mathbf{\hat{b}} \sin b \sin(S - B)+ \mathbf{\hat{c}} \sin c \sin(S - C)\]
<p>If we want to stop there that’s fine, but the form of the circumcenter given in the earlier post used the cross product of the vertices, suggesting a relationship with the polar triangle. So convert \(\mathbf{h}\) using the matrix given earlier:</p>
\[\mathbf{h}'
=
\begin{bmatrix}
\sin a & \cos c \sin b & \cos b \sin c \\
\cos c \sin a & \sin b & \cos a \sin c \\
\cos b \sin a & \cos a \sin b & \sin c
\end{bmatrix}
\mathbf{h}
=
\begin{bmatrix}
\sin(a) \sin(S-A) + \sin(b) \cos(c) \sin(S-B) + \sin(c) \cos(b) \sin(S-C),\\
\sin(b) \sin(S-B) + \sin(c) \cos(a) \sin(S-C) + \sin(a) \cos(c) \sin(S-A),\\
\sin(c) \sin(S-C) + \sin(a) \cos(b) \sin(S-A) + \sin(b) \cos(a) \sin(S-B),
\end{bmatrix}\]
<p>We’d like to have all angles (capital letters) so we can simplify. By the law of sines (and again, absorbing a constant term), we can replace \(\sin a\) and \(\sin A\), and the same for \(b\) and \(c\). We can replace \(\cos c\) using the second spherical law of cosines: \(\cos C = -\cos A \cos B + \sin A \sin B \cos c\), and correspondingly for \(a\) and \(b\). Let’s concentrate on the first term.</p>
\[\begin{split}
& \sin(A) \sin(S-A) + \sin(B) \cos(c) \sin(S-B) + \sin(C) \cos(b) \sin(S-C) \\
=
& \sin(A) \sin(S-A) + \frac{\sin(S-B)(\cos(C) + \cos(A) \cos(B))}{\sin(A)} + \frac{\sin(S-C)(\cos(B) + \cos(C) \cos(A))}{\sin(A)} \\
=
& 2 \cos(S - A) \cos(S - B) \cos(S - C)
\end{split}\]
<p>where we’re omitting a bunch of tedious trigonometric identities that I made Wolfram Alpha do anyways. Note that this is invariant under cyclic permutation of \(A\), \(B\), and \(C\), so the second and third elements of \(\mathbf{h}\) are the same quantity, and the polar transformation of the trimetric coordinates is \((1:1:1)\). To put it another way: The circumcenter of a spherical triangle is the incenter of its polar triangle. This fact is probably easier to prove in a directly geometric manner.</p>
<h2 id="orthocenter">Orthocenter</h2>
\[\mathbf{h} = (\sec A : \sec B : \sec C)\]
\[\mathbf{p} = \mathbf{\hat{a}} \frac{\sin a}{\cos A} + \mathbf{\hat{b}} \frac{\sin b}{\cos B} + \mathbf{\hat{c}} \frac{\sin c}{\cos C}\]
<p>Again, the first time I derived this the expression it was in terms of the cross products of the vertices, so let’s transform it to the polar triangle.</p>
\[\mathbf{h}'
=
\begin{bmatrix}
\sin a & \cos c \sin b & \cos b \sin c \\
\cos c \sin a & \sin b & \cos a \sin c \\
\cos b \sin a & \cos a \sin b & \sin c
\end{bmatrix}
\mathbf{h}
=
\begin{bmatrix}
\frac{\sin a }{\cos A} + \frac{\sin b \cos c }{\cos B} + \frac{\sin c \cos b}{\cos C},\\
\frac{\sin b }{\cos B} + \frac{\sin c \cos a }{\cos C} + \frac{\sin a \cos c}{\cos A},\\
\frac{\sin c }{\cos C} + \frac{\sin a \cos b }{\cos A} + \frac{\sin b \cos a}{\cos B}
\end{bmatrix}\]
<p>Like before, replace the side lengths with distances using the spherical laws of sines and cosines, and just focus on the first one.</p>
\[\begin{split}
& \frac{\sin A }{\cos A} + \frac{\sin B \cos c }{\cos B} + \frac{\sin C \cos b}{\cos C} \\
=
& \frac{\sin A }{\cos A } +
\frac{\cos C + \cos A \cos B }{\sin A \cos B } +
\frac{\cos B + \cos C \cos A }{\sin A \cos C } \\
=
& \frac{ (\cos A \cos B + \cos C ) (\cos A \cos C + \cos B )}{\sin A \cos A \cos B \cos C } \\
=
& \cos c \cos b \tan A \tan B \tan C \\
\end{split}\]
<p>Between the second and third forula a number of trig identities are omitted. The third step is transformed into the fourth step by applying the spherical law of cosines again. The tangent factors, taken together, are invariant under cyclic permutation. Eliminating the common factors, \(\mathbf{h}' = (\cos c \cos b: \cos c \cos b : \cos c \cos b)\), which is the form we used for the orthocenter in the earlier post. Dividing through by the product of the cosines of each edge gives \(\mathbf{h}' = (\sec a : \sec b : \sec c)\), which suggests that the orthocenter of a spherical triangle is also the orthocenter of its polar triangle.</p>Trilinear coordinates, a type of homogeneous coordinate, are very useful for the study of Euclidean triangles, especially that of triangle centers. They can be specified as a triplet of coordinates, \((x: y: z)\). Colons are used instead of commas to emphasize that these quantities are ratios: \((x: y: z)\) is the same point as \((kx: ky: kz)\) for any positive constant \(k\). The values x, y, and z are the perpendicular directed distance between the specified point and each side of a given triangle.Scaling the Schwarz triangle function2022-08-30T00:00:00+00:002022-08-30T00:00:00+00:00https://brsr.github.io/2022/08/30/schwarz-triangle-function-scale<p>Triangles in spherical and hyperbolic geometry have a property that Euclidean geometry does not: their angles determine their size. The area of a spherical triangle is equal to the angular excess, the sum of its interior angles minus \(\pi\). The area of a hyperbolic triangle is equal to the angular deficit, \(\pi\) minus the sum of its interior angles. The spherical or hyperbolic laws of sines and cosines behave similarly: they determine specific edge lengths.</p>
<p>The Schwarz triangle function, mentioned in a couple prior posts – <a href="/2022/03/03/conformal-polyhedral.html">1</a>, <a href="/2022/08/27/schwarz-triangle-function-edge.html">2</a> – is useful for conformal mapping of triangles in various geometries. However, it does not necessarily map to a triangle of the right size. In particular, triangles with an angle sum very close to \(\pi\) should be very small in spherical or hyperbolic geometry. The result of the Schwarz triangle function often must be scaled to obtain a properly-sized triangle for the geometry.</p>
<h1 id="metrics">Metrics</h1>
<p>Since we’re talking about size, we need to define what we mean by size, and we do that by the metric of whatever geometric space we’re operating in. The standard model for spherical geometry is the <a href="https://en.wikipedia.org/wiki/Riemann_sphere">Riemann sphere</a>, which has line element:</p>
\[ds^2 = \frac{4}{(1+x^2+y^2)^2} (dx^2 + dy^2)\]
<p>There are a few different ways to model hyperbolic geometry in the complex plane. Here we choose the <a href="https://en.wikipedia.org/wiki/Poincar%C3%A9_disk_model">Poincaré disk</a>, rather than the upper half-plane or some other model, since its line element is very similar to that of the Riemann sphere:</p>
\[ds^2 = \frac{4}{(1-(x^2+y^2))^2} (dx^2 + dy^2)\]
<p>The factor of 4 is so that the curvature of the surface is \(1\) for the sphere and \(-1\) for hyperbolic space.</p>
<p>We’ll look at the distance from \(s(0)=0\) to \(s(1)\), where \(s(z)\) is the Schwarz triangle function (not the differential in the line element). \(s(1)\) lies on the real line, so we can just ignore \(y\). Integrating the line element gives the distance function:</p>
\[\int_0^u ds = \int_0^u \frac{2}{1 \pm x^2} dx\]
<p>which is \(2 \arctan u\) for the Riemann sphere and \(2 \operatorname{artanh} u\) for the Poincaré disk.</p>
<p>For later, we note these equations:</p>
\[\begin{split}
\cos(2 \arctan u) &= \frac{1 - u^2}{1+u^2} \\
\cosh(2 \operatorname{artanh} u) &= \frac{1 + u^2}{1-u^2}
\end{split}\]
<h1 id="law-of-cosines">Law of cosines</h1>
<p>Consider the triangle with interior angles (in clockwise order) \(\pi \alpha\), \(\pi \beta\), and \(\pi \gamma\), and edge length \(\ell\) opposite of \(\beta\).
The <a href="https://en.wikipedia.org/wiki/Spherical_law_of_cosines">spherical law of cosines</a> gives</p>
\[\cos \beta = - \cos \alpha \cos \gamma + \sin \alpha \sin \gamma \cos \ell\]
<p>while the <a href="https://en.wikipedia.org/wiki/Hyperbolic_law_of_cosines">hyperbolic law of cosines</a> is the same thing with \(\cosh \ell\) instead of \(\cos \ell\):</p>
\[\cos \beta = - \cos \alpha \cos \gamma + \sin \alpha \sin \gamma \cosh \ell\]
<p>Solving for \(\cos \ell\) (or \(\cosh \ell\)) gives</p>
\[\frac{\cos \beta + \cos \alpha \cos \gamma}{\sin \alpha \sin \gamma}\]
<p>\(\ell\) is the distance in the geometry, rather than the untransformed distance in the plane: these are related by the distance functions we calculated earlier. The forms for the composition of \(\cos\) (or \(\cosh\)) and the distance function were given earlier. Combining everything and solving for \(u^2\) gives a remarkable result: the formulas for spherical and hyperbolic geometry are the same, except for the sign of the formula. The changeover point is where the angles indicate a Euclidean triangle, in which case \(u^2\) is zero. So combine the formulas using the absolute value, and take the root:</p>
\[u = \sqrt{\left| \frac{\cos(\pi (\alpha + \gamma)) + \cos(\pi \beta)}{\cos(\pi (\alpha - \gamma)) + \cos(\pi \beta) } \right|}\]
<p>Or, in terms of the Schwarz parameters mentioned in the first two articles:</p>
\[u = \sqrt{\left| \frac{\sin(\pi a) \sin(\pi b)}{\sin(\pi a') \sin(\pi b')} \right|}\]
<h1 id="scaling">Scaling</h1>
<p>So, an appropriately scaled Schwarz triangle function is:</p>
\[z' = s(z) \frac{u}{s(1)}\]
<p>The quantity \(u/s(1)\) can be expressed in terms of gamma functions (and a square root) by using the reflection formula to eliminate the \(\sin\)s, but unless you really need it in terms of gamma functions for some reason there’s no advantage to it.</p>
<p>For illustration, let’s look at the case of an equilateral triangle, where \(\alpha = \beta = \gamma\). \(u\) simplifies as so:</p>
\[u = \sqrt{\left| 2 \cos(\pi \alpha) - 1 \right|}\]
<p>Let’s plot \(u\), \(s(1)\), and \(u/s(1)\):</p>
<center><img src="/assets/images/Schwarz_triangle_function_scale.svg" alt="Graph of u, s(1), and u/s(1)" /></center>
<details>
<summary><i>Click here for the Python code to generate the plot above.</i></summary>
<pre>
import numpy as np
from scipy.special import gamma
import matplotlib.pyplot as plt
alpha = np.linspace(0, 1, 241)
beta = alpha
gam = alpha
a = (1 - alpha - beta - gam)/2
b = (1 - alpha + beta - gam)/2
c = 1 - alpha
ap = (1 + alpha - beta - gam)/2 # a - c + 1
bp = (1 + alpha + beta - gam)/2 # b - c + 1
cp = 1 + alpha # 2-c
s1 = gamma(1 - ap) * gamma(cp) * gamma(1 - bp)/(gamma(1 - a) * gamma(c) * gamma(1 - b))
s1[-1] = 2
u = np.sqrt(abs(np.sin(np.pi*a) * np.sin(np.pi*b) /
(np.sin(np.pi*ap) * np.sin(np.pi*bp))))
u[-1] = np.sqrt(3)
fig, ax = plt.subplots()
ax.plot(alpha, s1, label='s(1)')
ax.plot(alpha, u, label='u')
ax.plot(alpha, u/s1, label='u / s(1)')
ax.legend()
fig.savefig('Schwarz_triangle_function_scale.svg', bbox_inches='tight')
</pre>
</details>Triangles in spherical and hyperbolic geometry have a property that Euclidean geometry does not: their angles determine their size. The area of a spherical triangle is equal to the angular excess, the sum of its interior angles minus \(\pi\). The area of a hyperbolic triangle is equal to the angular deficit, \(\pi\) minus the sum of its interior angles. The spherical or hyperbolic laws of sines and cosines behave similarly: they determine specific edge lengths.Edges in the image of the Schwarz triangle function2022-08-27T00:00:00+00:002022-08-27T00:00:00+00:00https://brsr.github.io/2022/08/27/schwarz-triangle-function-edge<p><a href="https://commons.wikimedia.org/wiki/File:Schwarz_triangle_function.svg"><img src="/assets/images/Schwarz_triangle_function.svg" alt="Image of the upper half-plane transformed by the Schwarz triangle function with various parameters" height="300" align="right" /></a> <a href="/2022/03/03/conformal-polyhedral.html">A few posts ago, the Schwarz triangle function came up in the discussion of conformal map projections.</a> The Schwarz triangle function maps the upper half-plane to a triangle with circular arcs for edges. The real line (including infinity) becomes the boundary of the triangle. “Circular arc” should be understood to include straight lines, thought of as an arc of a circle with its center at infinity. In the image, you can see that two of those edges are straight lines. All are straight lines for the graph in the bottom left; its parameters define a mapping to a Euclidean triangle. For the other cases, can we determine the circle that the rightmost edge is part of?</p>
<h1 id="schwarz-triangle-function">Schwarz triangle function</h1>
<p>Let’s not repeat everything from the earlier post, just what’s relevant. The <a href="https://en.wikipedia.org/wiki/Schwarz_triangle_function">Schwarz triangle function</a> \(s(z)\) is parameterized by the three interior angles of the triangle, \(πα\), \(πβ\), and \(πγ\). If \(α +β +γ\) is greater than 1, the triangle is spherical; if equal to 1, Euclidean, and if less than 1, hyperbolic. \(πα\) is the interior angle at \(s(0)\), but the interior angle at \(s(1)\) is \(πγ\), and the angle at \(s(\infty)\) is \(πβ\). For some reason the angles are labeled in clockwise order even though counterclockwise is conventional in complex analysis. If it really annoys you, replace \(β\) with \(γ\) and vice versa.</p>
<p>\(α\), \(β\), \(γ\) can take values from 0 to 1. For an ideal triangle, all are 0: for a hemispherical triangle, all are 1. We define six parameters, and determine their range for later use:</p>
<table><tr>
<td>$$\begin{split}
&a &= (1−α−β−γ)/2 \in [-1, 1/2],\\
&a' &= (1+α−β−γ)/2 \in [-1/2, 1],
\end{split}$$</td>
<td>$$\begin{split}
&b &= (1−α+β−γ)/2 \in [-1/2, 1],\\
&b' &= (1+α+β−γ)/2 \in [0, 3/2],
\end{split}$$</td>
<td>$$\begin{split}
&c &= 1 − α \in [0, 1], \\
&c' &= 1 + α \in [1, 2].
\end{split}$$</td>
</tr></table>
<p>The transformed vertices can be expressed using <a href="https://en.wikipedia.org/wiki/Gamma_function">gamma functions</a>:</p>
\[\begin{aligned}
s(0) &= 0, \\
s(1) &= \frac
{\Gamma(1-a')\Gamma(1-b')\Gamma(c')}
{\Gamma(1-a)\Gamma(1-b)\Gamma(c)}, \\
s(\infty) &= \exp\left(i \pi \alpha \right)\frac
{\Gamma(1-a')\Gamma(b)\Gamma(c')}
{\Gamma(1-a)\Gamma(b')\Gamma(c)}.
\end{aligned}\]
<p>Define \(x_\infty\) as the real part of \(s(\infty)\) and \(y_\infty\) as the imaginary part, such that \(s(\infty) = x_\infty + i y_\infty\). Also, for consistency, define \(x_1 = s(1)\). \(s(1)\) is real, so \(y_1 = 0\).</p>
<h1 id="circle">Circle</h1>
<p>A circle in the plane has equation</p>
\[(x - x_c)^2 + (y - y_c)^2 = r^2,\]
<p>where \(r\) is the radius and \(x_c, y_c\) is the center of the circle. We’re expressing things as \(\mathbf{R}^2\) instead of \(\mathbf{C}\) for simplicity, but we can define \(z_c = x_c + i y_c\).</p>
<p>The equation of the circle can be rearranged as</p>
\[x^2 + y^2 = 2xx_c + 2yy_c + r^2 - x_c^2 - y_c^2\]
<p>Let \(u=2x_c\), \(v=2y_c\), and \(w = r^2 - x_c^2 - y_c^2\).</p>
\[x^2 + y^2 = u x + v y + w\]
<p>This can be used to create a linear system, but we only have two points on the circle, and three unknowns. However, we know the interior angles at the vertices \(s(1)\) and \(s(\infty)\), and we can use one of those to complete the system.</p>
<p>Taking the implicit derivative of the last equation gives:</p>
\[2x + 2y \frac{dy}{dx} = u + v \frac{dy}{dx}\]
<p>We know the slope of the tangent line at \(s(1)\), because we know the interior angle there. (We also know that for \(s(\infty)\), but it’s more complicated and we only need one to complete the system.) Therefore, at \(s(1)\),</p>
\[\frac{dy}{dx} = -\tan \left(\pi \gamma \right),\]
<p>and plugging that and the values for \(x\) and \(y\) in gives</p>
\[2x_1 = u - v \tan \left(\pi \gamma \right).\]
<h1 id="solving-the-system">Solving the system</h1>
<p>Bringing everything together into matrix form gives:</p>
\[\begin{bmatrix}
x_1 & 0 & 1\\
x_\infty & y_\infty & 1\\
1 & -\tan \left(\pi \gamma \right) & 0\\
\end{bmatrix}
\begin{bmatrix} u \\v \\ w
\end{bmatrix}
=
\begin{bmatrix} x_1^2 \\ x_\infty^2 + y_\infty^2\\ 2x_1
\end{bmatrix}.\]
<p>This system can be solved with <a href="https://en.wikipedia.org/wiki/Gaussian_elimination">Gaussian elimination</a> in a fairly straightforward if a bit tedious manner, resulting in:</p>
\[\begin{split}
u &= \frac{ 2 x_1 y_\infty - \tan \left(\pi \gamma \right) (x_1^2 - x_\infty^2 - y_\infty^2) }{y_\infty -\tan \left(\pi \gamma \right) (x_1 - x_\infty)} \\
v &= \frac{ (x_1 - x_\infty)^2 + y_\infty^2 }{y_\infty -\tan \left(\pi \gamma \right) (x_1 - x_\infty)} \\
w &= x_1 \frac{ (\tan \left(\pi \gamma \right) (x_1 x_\infty - x_\infty^2 - y_\infty^2) - y_\infty}{y_\infty -\tan \left(\pi \gamma \right) (x_1 - x_\infty)}
\end{split}\]
<p>Then, solving for \(x_c\), \(y_c\), and \(r\), splitting up the tangent function to avoid some unneccesary singularities, and simplifying a ton:</p>
\[\begin{split}
x_c &= \frac{ 2 x_1 y_\infty \cos \left(\pi \gamma \right) - \sin \left(\pi \gamma \right) (x_1^2 - x_\infty^2 - y_\infty^2) }{2 \left( y_\infty \cos \left(\pi \gamma \right) -(x_1 - x_\infty) \sin \left(\pi \gamma \right) \right)}\\
y_c &= \cos \left(\pi \gamma \right) \frac{ (x_1 - x_\infty)^2 + y_\infty^2 }{2 \left( y_\infty \cos \left(\pi \gamma \right) -(x_1 - x_\infty)\sin \left(\pi \gamma \right) \right)}\\
r &= \frac{x_1^2-2 x_1 x_\infty +x_\infty^2+y_\infty^2}{ 2 \left( y_\infty \cos \left(\pi \gamma \right) - (x_1 - x_\infty)\sin \left(\pi \gamma \right) \right)}
\end{split}\]
<p>This is useful if we already have \(x_1\), \(x_\infty\), and \(y_\infty\) calculated, which is probably true for most cases where you’d be interested in this formula. But it’s a little opaque: it doesn’t really give much insight. So…</p>
<h1 id="we-need-to-go-deeper">We need to go deeper!</h1>
<p>Let’s see if anything interesting comes out if we try to express it in terms of gamma functions. The derivations here are, as usual, too long to show, but they make use of the gamma function reflection formula, \(\Gamma(z) \Gamma(1-z) \sin(\pi z) = \pi\), and various identities for products and sums of sines and cosines.</p>
<p>These formulas are surprisingly simple, and share many factors:</p>
\[\begin{split}
x_c &= \left(\cos(\pi\beta) + \cos(\pi\alpha)\cos(\pi\gamma)\right)\frac
{\Gamma(1-a')\Gamma(1-b')\Gamma(c')\Gamma(a)\Gamma(b)}
{2\pi^2\Gamma(c)}, \\
y_c &= \sin(\pi\alpha)\cos(\pi\gamma)\frac
{\Gamma(1-a')\Gamma(1-b')\Gamma(c')\Gamma(a)\Gamma(b)}
{2\pi^2\Gamma(c)}\\
r &= \cos(\pi\alpha)\frac
{\Gamma(1-a')\Gamma(1-b')\Gamma(c')\Gamma(a)\Gamma(b)}
{2\pi^2\Gamma(c)}
\end{split}\]
<p>The gamma function has no zeros, and is infinite at 0 and the negative integers. Given the ranges for the parameters we determined earlier, this circle will be infinite when:</p>
<ul>
<li>\(a = 0\). This implies \(\alpha + \beta + \gamma = 1\), the Euclidean case mentioned earlier.</li>
<li>\(a = -1\). This implies \(\alpha = \beta = \gamma = 1\), which is the case when the triangle is a hemisphere.</li>
<li>\(b = 0\). This implies \(s(\infty) = \infty\), per the formula for \(s(\infty)\) given above.</li>
<li>\(a' = 1\). This implies \(s(\infty) = s(1) = \infty\), per their formulas.</li>
<li>\(b' = 1\). This implies \(s(1) = \infty\), per its formula.</li>
</ul>A few posts ago, the Schwarz triangle function came up in the discussion of conformal map projections. The Schwarz triangle function maps the upper half-plane to a triangle with circular arcs for edges. The real line (including infinity) becomes the boundary of the triangle. “Circular arc” should be understood to include straight lines, thought of as an arc of a circle with its center at infinity. In the image, you can see that two of those edges are straight lines. All are straight lines for the graph in the bottom left; its parameters define a mapping to a Euclidean triangle. For the other cases, can we determine the circle that the rightmost edge is part of?Area-preserving swirling of the disk2022-07-20T00:00:00+00:002022-07-20T00:00:00+00:00https://brsr.github.io/2022/07/20/swirled-disk<p>A consequence of the <a href="https://en.wikipedia.org/wiki/Riemann_mapping_theorem">Riemann mapping theorem</a> is that the conformal map from a given region of the sphere to a given region of the plane is essentially unique. Area-preserving maps, however, are not. For example, the
The <a href="https://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection">Lambert azimuthal equal-area projection</a> (left) is an azimuthal equal-area map projection, which takes the sphere to a disk. The <a href="https://en.wikipedia.org/wiki/Wiechel_projection">Wiechel projection</a> (right) is also an equal-area map projection, which resembles a swirled version of the Lambert projection. <a href="https://www.mapthematics.com/forums/viewtopic.php?f=8&t=716&sid=d27a60a94f4adecffdc1485668e8e486#p1714">As demonstrated on Daan Strebe’s forums</a>, the Wiechel projection has uniformly worse angular distortion than the Lambert projection, so its only real use is to demonstrate that equal-area map projectons aren’t unique.</p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/wiggles/identity.svg" title="Lambert">
<img src="/assets/images/wiggles/identity.svg" title="Lambert" alt="Lambert" />
<span>Lambert</span>
</a></li>
<li><a href="/assets/images/wiggles/wiechel_2.svg" title="Wiechel">
<img src="/assets/images/wiggles/wiechel_2.svg" title="Wiechel" alt="Wiechel" />
<span>Wiechel</span>
</a></li>
</ul>
<p>The Wiechel projection isn’t unusual. There is an infinite family of such equal-area map projectons to the disk. Those may be easier to understand as a transformation of the disk applied after the Lambert projection. Here we’ll look at some such transformations that are easy to describe.</p>
<h1 id="transformation-of-the-disk">Transformation of the disk</h1>
<p>Consider a transformation of the disk in <a href="https://en.wikipedia.org/wiki/Polar_coordinate_system">polar coordinates</a> given by</p>
\[\begin{split}
r_o &= r_i \\
\theta_o &= \theta_i + f\left(r_i\right)
\end{split}\]
<p>where \(f\) is an arbitrary differentiable function. If \(f(0) = 0\) this transformation preserves the orientation of the origin: if \(f(1) = 0\) it preserves the orientation of the boundary.</p>
<p>All such transformations are area-preserving. This can be proven using <a href="https://en.wikipedia.org/wiki/Jacobian_matrix_and_determinant">Jacobians</a>. This transformation is given polar coordinates, so we need to include the Jacobians of the transformation into and from polar coordinates. This is given as an example on the linked Wikipedia page: the Jacobian determinant of the transformation from polar coordinates to Cartesian coordinates is \(r\). The Jacobian determinant of the inverse transformation is just \(\frac{1}{r}\). Since the transformation described earlier has \(r_o = r_i\), the two cancel out, and we just need to examine the Jacobian determinant of the transformation itself:</p>
\[\begin{vmatrix}
1 & 0 \\
\frac{df}{dr_i} & 1
\end{vmatrix}\]
<p>which is clearly equal to 1 regardless of \(f\).</p>
<p>Note that the inverse transformation is given by \(-f\), and the identity is given by \(f = 0\). It’s also easy to show that these transformations are associative, so this is a group in the mathematical sense. The functions such that \(f(0) = 0\) or \(f(1) = 0\) form subgroups.</p>
<h1 id="linear-swirl">Linear swirl</h1>
<p>For these, \(f(r) = k r\) for some constant k. This is what’s usually implemented as “twirl” or “swirl” in graphics software like Photoshop. Somewhat notoriously, <a href="https://www.cbc.ca/news/canada/british-columbia/christopher-paul-neil-convicted-sex-offender-faces-10-new-charges-in-b-c-1.2590785">an international criminal attempted to disguise an image of himself he posted online by swirling his face, but Interpol recovered the original image by applying a swirl in the opposite direction.</a> (Content warning for mentions of sexual abuse.)</p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/wiggles/linear_4.svg" title="k = -π/4">
<img src="/assets/images/wiggles/linear_4.svg" title="k = -π/4" alt="k = -π/4" />
<span>k = -π/4</span>
</a></li>
<li><a href="/assets/images/wiggles/linear_2.svg" title="k = -π/2">
<img src="/assets/images/wiggles/linear_2.svg" title="k = -π/2" alt="k = -π/2" />
<span>k = -π/2</span>
</a></li>
<li><a href="/assets/images/wiggles/linear_1.svg" title="k = -π">
<img src="/assets/images/wiggles/linear_1.svg" title="k = -π" alt="k = -π" />
<span>k = -π</span>
</a></li>
</ul>
<h1 id="wiechel-swirl">Wiechel swirl</h1>
<p>For these, \(f(r) = k \arcsin r\) for some constant k. \(k = -\frac{1}{2}\) gives the transformation from the Lambert azimuthal equal-area projection to the Wiechel projection, and \(k = \frac{1}{2}\) gives the transformation from the Wiechel projection to the Lambert azimuthal equal-area projection.</p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/wiggles/wiechel_2.svg" title="k = -½">
<img src="/assets/images/wiggles/wiechel_2.svg" title="k = -½" alt="k = -½" />
<span>k = -½</span>
</a></li>
<li><a href="/assets/images/wiggles/wiechel_1.svg" title="k = -1">
<img src="/assets/images/wiggles/wiechel_1.svg" title="k = -1" alt="k = -1" />
<span>k = -1</span>
</a></li>
<li><a href="/assets/images/wiggles/wiechel_0.svg" title="k = -2">
<img src="/assets/images/wiggles/wiechel_0.svg" title="k = -2" alt="k = -2" />
<span>k = -2</span>
</a></li>
</ul>
<h1 id="wiggles">Wiggles</h1>
<p>We’re not limited to monotonic functions for \(f\). These ones use functions of the form \(f(r) = a \sin\left(br\right)\). <a href="https://youtu.be/V_OVxxIvqVw?t=45">Look at all of those wiggles!</a></p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 32%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/wiggles/wiggles_8.svg" title="a = π/8, b=π">
<img src="/assets/images/wiggles/wiggles_8.svg" title="a = π/8, b=π" alt="a = π/8, b=π" />
<span>a = π/8, b=π</span>
</a></li>
<li><a href="/assets/images/wiggles/wiggles_16.svg" title="a = π/16, b=3π">
<img src="/assets/images/wiggles/wiggles_16.svg" title="a = π/16, b=3π" alt="a = π/16, b=3π" />
<span>a = π/16, b=3π</span>
</a></li>
<li><a href="/assets/images/wiggles/wiggles_32.svg" title="a = π/32, b=8π">
<img src="/assets/images/wiggles/wiggles_32.svg" title="a = π/32, b=8π" alt="a = π/32, b=8π" />
<span>a = π/32, b=8π</span>
</a></li>
</ul>
<h1 id="angle-distortion">Angle distortion</h1>
<p>None of these are improvements on the Lambert projection, at least in terms of angle distortion. Without getting into a lengthy calculation, notice that other transformations alter the angle at which meridians meet circles of latitude, particularly at the equator where, on the sphere, meridians intersect at right angles. However, it is interesting that we can make the angle distortion as bad as we like, for example by choosing an arbitrary large \(k\).</p>
<p>If you want some area-preserving transformations to make a better map instead of a worse one, I recommend this paper: <a href="https://doi.org/10.1080/15230406.2018.1452632">Daniel “daan” Strebe (2018): A bevy of area-preserving transforms for map projection designers, Cartography and Geographic Information Science, DOI: 10.1080/15230406.2018.1452632</a>.</p>
<p><em>A Python script to create the figures in this post is located <a href="https://github.com/brsr/mapproj/blob/master/bin/swirls.py">here</a>.</em></p>A consequence of the Riemann mapping theorem is that the conformal map from a given region of the sphere to a given region of the plane is essentially unique. Area-preserving maps, however, are not. For example, the The Lambert azimuthal equal-area projection (left) is an azimuthal equal-area map projection, which takes the sphere to a disk. The Wiechel projection (right) is also an equal-area map projection, which resembles a swirled version of the Lambert projection. As demonstrated on Daan Strebe’s forums, the Wiechel projection has uniformly worse angular distortion than the Lambert projection, so its only real use is to demonstrate that equal-area map projectons aren’t unique.Some dubious ways to calculate conformal polyhedral projections2022-03-03T00:00:00+00:002022-03-03T00:00:00+00:00https://brsr.github.io/2022/03/03/conformal-polyhedral<p>(The title of this post is in tribute to Moler and Van Loan’s classic paper “<a href="https://doi.org/10.1137/S00361445024180">Nineteen Dubious Ways to Compute the Exponential of a Matrix</a>.”)</p>
<p>Conformal map projections are deeply connected to the theory of complex analysis of a single variable, which is at this point in time is very mature. One case of interest is transforming the faces of a spherical polyhedron into Euclidean polygons in the plane, and Adams basically had a mature description of that by 1925.<sup id="fnref:Adams" role="doc-noteref"><a href="#fn:Adams" class="footnote" rel="footnote">1</a></sup> The best description of these projections is contained in Lee’s 1976 monograph, which updates and fixes some errors in Adams.<sup id="fnref:Lee" role="doc-noteref"><a href="#fn:Lee" class="footnote" rel="footnote">2</a></sup> While Lee’s work is a little dated, it remains the most complete description. Except for simple cases like the mapping of a hemisphere to a square,<sup id="fnref:Stark" role="doc-noteref"><a href="#fn:Stark" class="footnote" rel="footnote">3</a></sup> few have improved on Lee’s work. However, these projections aren’t used very often. I believe part of this is that, despite the well-developed theory of conformal polyhedral projections, they’re kind of a pain in the neck to actually calculate or implement.</p>
<p>This does not intend to be a complete description: Lee’s monograph is freely available on archive.org, and also a hundred pages long.<sup id="fnref:Lee:1" role="doc-noteref"><a href="#fn:Lee" class="footnote" rel="footnote">2</a></sup> Instead, this is a high-level summary. The transformation of a face of a spherical polyhedron can be described as a composition of three functions. Let’s not be too fussy about the domains and codomains of the functions, but we do need to include the point at infinity of the extended complex plane (the <a href="https://en.wikipedia.org/wiki/Riemann_sphere">Riemann sphere</a>). Let \(z\) be a complex number and \(\lambda, \phi\) be latitude and longitude.</p>
<ul>
<li>\(A(\lambda, \phi)\): Use the stereographic projection to transform a geodesic polygon on the sphere to a polygon in the complex plane having circular arcs for edges.</li>
<li>\(B(z)\): Conformally transform that arc-edged polygon to some convenient region in the complex plane, usually the upper half-plane or unit disk.</li>
<li>\(C(z)\): Conformally transform that region to the interior of a Euclidean polygon.</li>
</ul>
<p>Thus, the forward projection is \(C(B(A(\lambda, \phi)))\), and the inverse is \(A^{-1}(B^{-1}(C^{-1}(z)))\). For example, to transform a face of a spherical octahedron to an equilateral triangle, the results at each step look like this:</p>
<table><tr>
<th><img src="/assets/images/conformal/conformaltriangle1.svg" alt="Triangle on the sphere in orthographic projection" /></th>
<th><center>A<br />↔</center></th>
<th><img src="/assets/images/conformal/conformaltriangle2.svg" alt="Arc-edged triangle in the plane" /></th>
<th><center>B<br />↔</center></th>
<th><img src="/assets/images/conformal/conformaltriangle3.svg" alt="Upper half plane" /></th>
<th><center>C<br />↔</center></th>
<th><img src="/assets/images/conformal/conformaltriangle4.svg" alt="Euclidean triangle in the plane" /></th>
</tr></table>
<p>The stereographic projection \(A\) is well documented and does not need to be elaborated on here. Large-scape projections like these are usually used in spherical form, but if you really want you can use the ellipsoidal form of the stereographic projection: see pages 160 – 163 of Snyder.<sup id="fnref:Snyder" role="doc-noteref"><a href="#fn:Snyder" class="footnote" rel="footnote">4</a></sup></p>
<h1 id="preliminaries">Preliminaries</h1>
<p>The <a href="https://en.wikipedia.org/wiki/Schwarz_triangle_function">Schwarz triangle function</a> transforms the upper half-plane to a triangle: spherical, Euclidean, or hyperbolic depending on the angles given. For a triangle with interior angles \(πα\), \(πβ\), and \(πγ\), the formula for the Schwarz triangle function \(s(z)\) is:<sup id="fnref:Nehari" role="doc-noteref"><a href="#fn:Nehari" class="footnote" rel="footnote">5</a></sup></p>
\[s(z) = z^{\alpha} \frac{_2 F_1 \left(a', b'; c'; z\right)}{_2 F_1 \left(a, b; c; z\right)}\]
<p>where \(_2 F_1 \left(a, b; c; z\right)\) is a <a href="https://en.wikipedia.org/wiki/Hypergeometric_function">hypergeometric function</a> and</p>
<table><tr>
<td>$$\begin{split}
&a &= (1−α−β−γ)/2,\\
&a' &= (1+α−β−γ)/2,
\end{split}$$</td>
<td>$$\begin{split}
&b &= (1−α+β−γ)/2,\\
&b' &= (1+α+β−γ)/2,
\end{split}$$</td>
<td>$$\begin{split}
&c &= 1 − α, \\
&c' &= 1 + α.
\end{split}$$</td>
</tr></table>
<p>The function \(s(z)\) maps \(z = 0\) to the vertex having angle \(πα\), \(z = 1\) to the vertex having angle \(πγ\), and \(z = \infty\) to the vertex having angle \(πβ\). The transformed vertices can be expressed using <a href="https://en.wikipedia.org/wiki/Gamma_function">gamma functions</a>:</p>
\[\begin{aligned}
s(0) &= 0, \\
s(1) &= \frac
{\Gamma(1-a')\Gamma(1-b')\Gamma(c')}
{\Gamma(1-a)\Gamma(1-b)\Gamma(c)}, \\
s(\infty) &= \exp\left(i \pi \alpha \right)\frac
{\Gamma(1-a')\Gamma(b)\Gamma(c')}
{\Gamma(1-a)\Gamma(b')\Gamma(c)}.
\end{aligned}\]
<p>The boundary of the triangle is the image of the real line.</p>
<p>Also useful are <a href="https://en.wikipedia.org/wiki/M%C3%B6bius_transformation">Möbius transformations</a>, which conformally map the Riemann sphere to itself. Möbius transformations map circles to circles, if you consider a line to be a circle passing through the point at infinity. These can be used to map the upper half-plane to the unit disk, choosing which points on the real line are mapped to which points on the unit circle as you require.</p>
<h1 id="step-b-nice-in-very-common-but-very-restricted-scenarios">Step B: Nice in very common but very restricted scenarios</h1>
<p>Any polygon (spherical or Euclidean) can be divided into triangles, so it’s enough to transform each triangle and then stitch them together later. So all we have to do is invert that Schwarz triangle function. Easy, right? Well, not for arbitrary triangles, but for the usual symmetric “polyhedral globe” setups it is.</p>
<p>More specifically, for a spherical <a href="https://en.wikipedia.org/wiki/Schwarz_triangle">Schwarz triangle</a>, then the inverse of \(s(z)\) can be written as a rational function. A <a href="https://en.wikipedia.org/wiki/Schwarz_triangle">Schwarz triangle</a> is (loosely) a triangle that can tile a sphere (or the plane, or hyperbolic space) by reflections. If the original polygon isn’t a Schwarz triangle it may be subdividable into Schwarz triangles: other spherical polyhedra, squares, pentagons, etc. can also be subdivided this way. So, let’s take \(B(z) = s^{-1}(\frac{z}{k})\), where \(k > 0\) is some real number to scale the input to the Schwarz function appropriately. Lee gave formulas for \(B(z)\) for the subdivided faces of platonic solids and other shapes.<sup id="fnref:Lee:2" role="doc-noteref"><a href="#fn:Lee" class="footnote" rel="footnote">2</a></sup></p>
<p>Let’s see a simple example. The faces of the octahedron are already Schwarz triangles, so do not need to be subdivided, and its rational function is particularly simple. Specifically, orient the octahedron is oriented so two vertices lie at the “poles” and the rest lie along the equator, and apply the stereographic projection centered on a pole so that that pole is mapped to 0, the other is mapped to \(\infty\), and the equator vertices are mapped to \(1, i, -1, -i\). Then the function is</p>
\[B(z) = \frac{4z^2}{(1+z^2)^2}\]
<p>The North and South Poles, at 0 and \(\infty\) on the Riemann sphere, are mapped to 0. The equator vertices at \(1\) and \(-1\) go to 1, and those at \(i\) and \(-i\) go to \(\infty\). This function maps faces of the octahedron alternately to the upper and lower half plane.</p>
<p>In this particular case, the inverse of \(B(z)\) has a nice analytic form:</p>
\[B^{-1}(z) = \pm \sqrt{\pm \frac{2\sqrt{1-z}}{z} + \frac{2}{z}-1 }\]
<p>where the two \(\pm\) signs are independent of each other. In general, however, \(B^{-1}(z)\) can’t be expressed simply: the Schwarz triangle formula using hypergeometric functions is often as good as you can get.</p>
<h1 id="step-c-time-for-elliptic-functions">Step C: Time for elliptic functions</h1>
<p>In step C, since the target triangle is a Euclidean triangle, \(\alpha + \beta + \gamma = 1\). The hypergeometric function in the denominator reduces to 1, and the whole expression becomes:</p>
\[C(z) = s(z) = z^{\alpha} \,_2 F_1 \left(\alpha, \alpha+\beta; 1 + \alpha; z\right)\]
<p>\(C^{-1}(z)\) can be expressed in terms of elliptic functions. In general the construction of the inverse is somewhat involved, <a href="https://math.stackexchange.com/questions/246309/conformal-mapping-from-triangle-to-upper-half-plane-in-terms-of-weierstrass-wp">as shown in this math.stackexchange page</a>. However, there is one well-known special case, and one less-well-known special case, that are easier to handle.</p>
<h2 id="squares">Squares</h2>
<p>The <a href="https://en.wikipedia.org/wiki/Jacobi_elliptic_functions">Jacobi elliptic functions</a> can be used to map between a square and the unit disk. The <a href="https://en.wikipedia.org/wiki/Elliptic_integral#Incomplete_elliptic_integral_of_the_first_kind">incomplete elliptic integral of the first kind</a> is its inverse, so in this case we can replace the formula for \(C(z)\) with a different, somewhat simpler special function. Let \(\operatorname{cn}(z, k)\) be the elliptic cosine Jacobi function in terms of modulus, and let \(F(\varphi, k)\) be the incomplete elliptic integral of the first kind in terms of the amplitude and modulus.</p>
<p>Transforming a hemisphere to a square is the simplest of these transformations, and a useful example. \(A\) remains the stereographic projection, mapping a hemisphere to the unit disk, but \(B\) is the identity function, keeping the center of the hemisphere at the origin, and then \(C\) is as so:<sup id="fnref:Fong" role="doc-noteref"><a href="#fn:Fong" class="footnote" rel="footnote">6</a></sup></p>
\[\begin{split}
C(z) &= \frac{\sqrt{1-i}}{-K} F\left(\arccos \left( \frac{1+i}{\sqrt{2}} z \right), \frac{1}{\sqrt{2}}\right) + 1 - i\\
C^{-1}(z) &= \frac{\sqrt{1-i}}{\sqrt{2}} \operatorname{cn} \left( K \frac{1+i}{2} z - K, \frac{1}{\sqrt{2}}\right)
\end{split}\]
<p>where \(K = F\left(\frac{\pi}{2}, \frac{1}{\sqrt{2}}\right)\).</p>
<h2 id="equilateral-triangles">Equilateral triangles</h2>
<p>The <a href="https://en.wikipedia.org/wiki/Dixon_elliptic_functions">Dixon elliptic function</a> can be used to map an equilateral triangle to the unit disk. Chapter 4 of Lee covers this transformation, giving formulas for the projection of the whole earth, a hemisphere, triangle-faced platonic solids, and so on into one or more equilateral triangles. All involve the inversion of the functions \(\operatorname{sm}\) and/or \(\operatorname{cm}\) for the forward transformation. The Dixon elliptic functions do not have a simple inverse that I know of, and even Lee resorts to the form using hypergeometric functions.</p>
<p>The Dixon elliptic functions are obscure, and nearly only come up in discussions about conformal map projections. However, Dixon elliptic functions can be expressed in terms of Jacobi elliptic functions, as mentioned on the Wikipedia article.</p>
<h1 id="so-whats-the-catch">So what’s the catch?</h1>
<p>How do we calculate all these special functions?</p>
<p>Calculating the hypergeometric function over the entire upper half-plane is not straightforward. See the (lengthy) <a href="https://dlmf.nist.gov/15">NIST Digital Library of Mathematical Functions entry</a>. A numerically well-behaved implementation must make use of a number of different transformations and formulas. Full-fledged software implementations are uncommon. SciPy does implement hyperbolic function of complex arguments, <a href="https://github.com/scipy/scipy/pull/14706">but only recently did they fix a long-standing bug and make it correct in the entire complex plane</a>, which demonstrates how difficult it is to implement well. Even if you do have a usable implementation of the hypergeometric function available, it’s expensive to calculate.</p>
<p>The elliptic functions and integrals are simpler but still complicated. The most commonly used implementations are those in <a href="https://netlib.org/cephes/">Cephes</a>, which are only implemented for real arguments: formulas to separate the real and imaginary parts are necessary. There are more considerations after that. Stark’s 2009 paper<sup id="fnref:Stark:1" role="doc-noteref"><a href="#fn:Stark" class="footnote" rel="footnote">3</a></sup> on the disk-to-square mapping dedicates sections 3 and 4, a decent chunk of the paper by length, to a stable and fast evaluation of \(F\). He splits the unit disk into three regions, each one using a different numerical technique.</p>
<p>Lee’s monograph is the length that it is because of all the numerical methods included. And honestly, there has not been a radical improvement in those methods since he was writing in 1976. Some calculations are still long and complicated.</p>
<h1 id="conclusion">Conclusion</h1>
<p>On one hand, the theory here has been settled for some time, and the steps are documented. But on the other, those steps are more complicated to calculate than they look on the surface. For Adams to have calculated all this in 1925 must have been very time-consuming. You’re also up a creek if you want to use an asymmetric polyhedron. Given that polyhedral projections are more often seen as novelties instead of practically useful, it’s understandable that most GIS software doesn’t bother.</p>
<p><em>A Python script to create the figures in this post is located <a href="https://github.com/brsr/mapproj/blob/master/bin/conformal_polyhedral.py">here</a>.</em></p>
<h1 id="references">References</h1>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:Adams" role="doc-endnote">
<p>Adams, Oscar S. (1925). Elliptic Functions Applied to Conformal World Maps. Issue 297 of United States Coast and Geodetic Survey Serial. U.S. Government Printing Office. <a href="#fnref:Adams" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Lee" role="doc-endnote">
<p>Lee, Laurence (1976). <a href="https://archive.org/details/conformalproject0000leel">Conformal Projections based on Elliptic Functions.</a> Cartographica Monographs. 16. University of Toronto Press. Also in <a href="https://www.utpjournals.press/toc/cart/13/1">The Canadian Cartographer. 13 (1). 1976</a>. <a href="#fnref:Lee" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:Lee:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:Lee:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a></p>
</li>
<li id="fn:Stark" role="doc-endnote">
<p>Stark, Michael M. (2009) <a href="https://doi.org/10.1080/2151237X.2009.10129277">Fast and Stable Conformal Mapping Between a Disc and a Square</a>. Journal of Graphics, GPU, and Game Tools, 14:2, 1–23. <a href="#fnref:Stark" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:Stark:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:Snyder" role="doc-endnote">
<p>Snyder, John P. (1987). <a href="https://archive.org/details/Snyder1987MapProjectionsAWorkingManual">Map Projections—A Working Manual</a>. <a href="https://pubs.er.usgs.gov/publication/pp1395">United States Geological Survey Professional Paper 1395</a>. <a href="#fnref:Snyder" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Nehari" role="doc-endnote">
<p>Nehari, Ze’ev (1975). Mapping Properties of Special Functions: The Schwarzian \(s\)-functions. Chapter 6, section 5 of Conformal Mapping. Dover Pubs, NY pp 308–316. <a href="#fnref:Nehari" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Fong" role="doc-endnote">
<p>Fong, Chamberlain (2015). <a href="https://squircular.blogspot.com/2015/09/schwarz-christoffel-mapping.html">Schwarz-Christoffel mapping</a>. <a href="#fnref:Fong" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>(The title of this post is in tribute to Moler and Van Loan’s classic paper “Nineteen Dubious Ways to Compute the Exponential of a Matrix.”)A variation on the Chamberlin trimetric map projection2021-10-02T00:00:00+00:002021-10-02T00:00:00+00:00https://brsr.github.io/2021/10/02/chamberlin-variation<p><a href="https://www.tandfonline.com/doi/full/10.1080/15230406.2021.1975571">My paper “A variation on the Chamberlin trimetric map projection” was just published in Cartography and Geographic Information Science.</a> If you don’t have institutional access, <a href="https://github.com/brsr/trimetric/blob/main/tex/chamberlin_variation.pdf">the preprint is on my github repo</a>.</p>
<p><strong>The casual summary:</strong> A compromise map projection is one that isn’t <a href="https://en.wikipedia.org/wiki/Equal-area_map">area-preserving</a> or <a href="https://en.wikipedia.org/wiki/Conformal_map_projection">conformal</a> (equal-angle). Conformal map projections have a lot of area distortion, and equal-area map projections have a lot of angle distortion. Compromise projections can have less noticable distortion than conformal or equal-area map projections. The concept of the just-noticable difference from <a href="https://en.wikipedia.org/wiki/Psychophysics">psychophysics</a> is relevant: for visual stimuli, the just-noticable difference is in the ballpark of 5%.</p>
<p><a href="https://en.wikipedia.org/wiki/Chamberlin_trimetric_projection">The Chamberlin trimetric map projection</a> is a compromise map projection, useful for maps of continents and large regions. Without going into detail, it uses triangulation. It has a nice geometric construction, but the corresponding algebraic formula is long and fussy. It also lacks an easy-to-calculate inverse.</p>
<p>By changing how the triangulation is done very slightly, a projection with a much nicer algebraic formula was found. This was called the Matrix trimetric projection, since the formula involves the product of a 3x3 matrix with a vector. It takes about half the time to calculate as the Chamberlin projection. The formula can be inverted easily using a simple one-parameter <a href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton’s method</a> iteration. The Matrix trimetric causes slightly more area and angle distortion than the Chamberlin, but it’s still in the ballpark of that just-noticable difference.</p>
<p><strong>The personal summary:</strong> This was my COVID project. A good distraction from doomscrolling and compulsively reloading COVID dashboards, I suppose. I was intimidated by submitting an academic paper as someone who’s not affiliated with an institution any more, but it turned out to be a non-issue.</p>My paper “A variation on the Chamberlin trimetric map projection” was just published in Cartography and Geographic Information Science. If you don’t have institutional access, the preprint is on my github repo.Snyder’s equal-area projection2021-08-31T00:00:00+00:002021-08-31T00:00:00+00:00https://brsr.github.io/2021/08/31/snyder-equal-area<p>John P Snyder, author of many useful articles and books on map projections, created an equal-area projection called (in an aversion of <a href="https://en.wikipedia.org/wiki/Stigler%27s_law_of_eponymy">Stigler’s Law</a>) Snyder’s equal-area projection.<sup id="fnref:Snyder" role="doc-noteref"><a href="#fn:Snyder" class="footnote" rel="footnote">1</a></sup> Snyder’s projection was designed for polyhedral globes and maps. The best-known example of a polyhedral map might be Buckminster Fuller’s <a href="https://en.wikipedia.org/wiki/Dymaxion_map">Dymaxion map</a>, based on an <a href="https://en.wikipedia.org/wiki/Icosahedron">icosahedron</a>.</p>
<p>Snyder looked at the platonic solids and the truncated icosahedron. Each face of the polyhedron was subdivided into isosceles triangles using the center point and the vertices of the face. Even triangular faces were subdivided this way, to maintain symmetry. These triangles on the sphere were transformed into triangles in the plane and then reassembled. In a broad sense, this projection includes the method of subdividing the sphere as well as the function between the spherical triangle and the planar triangle. In a narrow sense, the projection is just the function between a triangle on the sphere and a triangle on the plane. That is what this post focuses on: that projection, considered on its own.</p>
<h1 id="vector-form">Vector form</h1>
<p>Snyder’s projection is restated here in vector form. Other have noticed that projections related to Snyder’s projection are simpler to express in terms of unit vectors rather than latitude and longitude,<sup id="fnref:Patt" role="doc-noteref"><a href="#fn:Patt" class="footnote" rel="footnote">2</a></sup> and this turns out to be true for Snyder’s projection as well. As usual, reference <a href="/2021/05/01/vector-spherical-geometry.html">the introductory article on spherical geometry with vectors</a> if needed.</p>
<p>Time for a whole bunch of definitions. Let \(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2\) be points on the sphere, in counterclockwise order. and let \(\mathbf V = [\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2]\) be a matrix having those vectors as columns. Let \(\mathbf{\hat{v}} = [v_x, v_y, v_z]\) be another point on the sphere. Let \(\beta_i\) be barycentric coordinates such that \(\beta_0 + \beta_1 + \beta_2 = 1\). Let \(A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2)\) denote the signed area of the triangle made up of those vertices, positive for counterclockwise order.</p>
<h2 id="forward">Forward</h2>
<p>Leaving out some of the nitty-gritty of the derivation, first find the point \(\mathbf{\hat{p}}\) where the great circle passing through \(\mathbf{\hat{v}}_0\) and \(\mathbf{\hat{v}}\) and the great circle passing through \(\mathbf{\hat{v}}_1\) and \(\mathbf{\hat{v}}_2\).</p>
\[\mathbf{\hat{p}} = \frac{(\mathbf{\hat{v}}_0 \times \mathbf{\hat{v}}) \times (\mathbf{\hat{v}}_1 \times \mathbf{\hat{v}}_2)}{\|\ldots\|}
= \frac{
|\mathbf{V}| \mathbf{\hat{v}} -
|\mathbf{\hat{v}}, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2| \mathbf{\hat{v}}_0
}{\|\ldots\|}\]
<p>Then find the distance from \(\mathbf{\hat{v}}_0\) to \(\mathbf{\hat{p}}\), and relate it to the distance from \(\mathbf{\hat{v}}_0\) to \(\mathbf{\hat{v}}\) in a way that preserves area.</p>
\[h = \sqrt{\frac{1 - \mathbf{\hat{v}}_0 \cdot \mathbf{\hat{v}}}
{1 - \mathbf{\hat{v}}_0 \cdot \mathbf{\hat{p}}}}\]
<p>Then one of the coordinates can be found in terms of \(b\) and the fraction of the area contained to one side of the line from \(\mathbf{\hat{v}}_0\) to \(\mathbf{\hat{p}}\):</p>
\[\beta_2 = h \frac{A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}})}
{A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2)}\]
<p>Finally, \(\beta_0 = 1 - h\), and \(\beta_1 = h - \beta_2\).</p>
<h2 id="inverse">Inverse</h2>
<p>The inverse formula is lengthy, but follows straightforwardly from the formward formula. Contrary to Snyder’s original paper<sup id="fnref:Snyder:1" role="doc-noteref"><a href="#fn:Snyder" class="footnote" rel="footnote">1</a></sup> and a paper that followed<sup id="fnref:Harrison" role="doc-noteref"><a href="#fn:Harrison" class="footnote" rel="footnote">3</a></sup>, it does have a closed form solution.</p>
<p>Let \(c_{ij} = \mathbf{\hat{v}}_i \cdot \mathbf{\hat{v}}_j\), and \(s_{ij} = \sqrt{1-c_{ij}^2} = \| \mathbf{\hat{v}}_i \times \mathbf{\hat{v}}_j \|\).</p>
\[\begin{split}
h &= 1 - \beta_0 \\
a &= \frac{\beta_2}{h} A\left(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2\right)\\
S &= \sin(a) \\
C &= 1 - \cos(a) \\
f &= S |\mathbf{V}| + C \left(c_{01} c_{12} - c_{20}\right) \\
g &= C s_{12} \left(1 + c_{01}\right) \\
q &= \frac{2}{\arccos \left(c_{12} \right)} \arctan\left( \frac{g}{f} \right) \\
\mathbf{\hat{p}} &= \operatorname{Slerp}\left(\mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2; q\right) \\
t &= \frac{\arccos \left( 1 + h^2 (\mathbf{\hat{v}}_0 \cdot \mathbf{\hat{p}} - 1)\right)}
{\arccos \left(\mathbf{\hat{v}}_0 \cdot \mathbf{\hat{p}} \right)} \\
\mathbf{\hat{v}} &= \operatorname{Slerp}\left(\mathbf{\hat{v}}_0, \mathbf{\hat{p}}; t\right)
\end{split}\]
<h1 id="special-cases">Special cases</h1>
<p>Some special cases simplify significantly. For brevity I’ll just do the forward formulas.
For both of these, let \(\mathbf{z}_0 = [0,0]\), \(\mathbf{z}_1 = [1,-1]\), and \(\mathbf{z}_2 = [1, 1]\), and define \(\mathbf{z}=[x, y]\) in terms of barycentric coordinates: \(\mathbf{z} = \sum \mathbf{z}_i \beta_i\), or in terms of components directly,</p>
\[\begin{split}
x &= &\beta_1 + \beta_2 = h,\\
y &= -&\beta_1 + \beta_2 = 2\beta_2 - h
= h \left(2\frac{A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}})}
{A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2)} - 1\right)
\end{split}\]
<p>Also recall <a href="/2021/05/01/vector-spherical-geometry.html">the formula for a vector in terms of latitude and longitude</a>:</p>
\[\mathbf{\hat{v}} =
\begin{bmatrix}
v_x \\ v_y \\ v_z
\end{bmatrix}
=
\begin{bmatrix}
\cos(\varphi) \cos(\lambda) \\
\cos(\varphi) \sin(\lambda) \\
\sin(\varphi)
\end{bmatrix}.\]
<h2 id="hemisphere-to-square">Hemisphere to square</h2>
<p><img src="/assets/images/snyder/hemisphere.svg" alt="Diagram of projection from hemisphere to plane" height="150" align="right" />
Consider a hemisphere with four evenly spaced vertices along its boundary, a hemispherical square if you will. Using the center point, this can be divided into four triangles, effectively forming a spherical octahedron. The following derivation is for the triangle in green.</p>
<p>Let \(\mathbf{\hat{v}}_0 = [0, 0, 1]\), \(\mathbf{\hat{v}}_1 = \frac{1}{\sqrt{2}}[1, -1, 0]\), and \(\mathbf{\hat{v}}_2 = \frac{1}{\sqrt{2}}[1, 1, 0]\). Then \(\mathbf{\hat{v}}_i \cdot \mathbf{\hat{v}}_j = 0\) for all \(i \ne j\), and \(A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2) = \frac{\pi}{2}\).</p>
<p>First, note that \(\mathbf{\hat{p}}\) lies in the same plane as \(\mathbf{\hat{v}}_1\) and \(\mathbf{\hat{v}}_2\), so \(\mathbf{\hat{p}} \cdot \mathbf{\hat{v}}_0\) is also 0. Also recognize that \(\varphi \in [-\frac{\pi}{2}, \frac{\pi}{2}]\). Thus, \(h\) simplifies as so:</p>
\[h = \sqrt{1 - \hat{v}_z} = \sqrt{1 - \sin(\varphi)} = \sqrt{2} \sin\left(\frac{\pi}{4} - \frac{\varphi}{2}\right).\]
<p>Second, note that the interior angle at vertex \(\mathbf{\hat{v}}_1\) is a right angle, and so is the interior angle at \(\mathbf{\hat{p}}\). From the fact that the area of a spherical triangle is the sum of its interior angles minus \(\pi\), it follows that \(A\left(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}}\right) = \frac{\pi}{4} + \lambda\), so:</p>
\[\beta_2 = h \left( \frac{2}{\pi}\lambda + \frac{1}{2}\right).\]
<p>Combining everything gives this formula:</p>
\[\begin{split}
x &= \sqrt{2} \sin\left(\frac{\pi}{4} - \frac{\varphi}{2}\right),\\
y &= \frac{4}{\pi} x \lambda.
\end{split}\]
<p>This is equivalent to the formula for the <a href="https://en.wikipedia.org/wiki/Collignon_projection">Collignon projection</a> with an affine transformation. Snyder didn’t mention it in his paper, despite having included the Collignon projection in his 1989 <a href="https://doi.org/10.3133%2Fpp1453">Album of Map Projections</a> with Voxland.<sup id="fnref:Voxland" role="doc-noteref"><a href="#fn:Voxland" class="footnote" rel="footnote">4</a></sup> Snyder may not have been interested in the hemisphere case: he didn’t include any hemisphere examples in his paper.</p>
<p>Lambers (not Lambert) in a paper “Mappings between sphere, disc, and square”<sup id="fnref:Lambers" role="doc-noteref"><a href="#fn:Lambers" class="footnote" rel="footnote">5</a></sup> used a mapping from a hemisphere to a square that is a composition of the <a href="https://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection">Lambert azimuthal equal-area projection</a> and the Shirley-Chiu equal-area mapping between the disk and the square.<sup id="fnref:Chiu" role="doc-noteref"><a href="#fn:Chiu" class="footnote" rel="footnote">6</a></sup> This, when restricted to a single quadrant, is also equivalent to the Collignon projection with an affine transformation. This is easiest to see in polar form:</p>
\[\begin{split}
\left(r, \Theta \right) &= \left( \sqrt{2} \sin \left(\frac{\pi}{4} - \frac{\varphi}{2}\right), \theta\right) \\
\left(x, y \right) &= \left(r, \frac{4}{\pi}r\Theta\right),\, \Theta \in [-\frac{\pi}{4}, \frac{\pi}{4}]
\end{split}\]
<p>The map can be applied to other triangles by negating \(\varphi\), \(x\), and \(y\), and/or replacing \(\lambda\) with \((\lambda - \lambda_0)\), where \(\lambda_0\) is the meridian passing through the center of the face. It may be necessary to add or subtract \(2\pi\) from \((\lambda - \lambda_0)\) to move it into the appropriate range.
The projection for a triangle from a hemisphere divided into 3 parts, or generally a hemisphere divided into \(n\) parts, is the same up to affine transformation.</p>
<h2 id="cube-face-to-square">Cube face to square</h2>
<p><img src="/assets/images/snyder/cube.svg" alt="Diagram of projection from cube to plane" height="150" align="right" />
Now consider a cube on the sphere. Dividing each face into triangles creates a spherical <a href="https://en.wikipedia.org/wiki/Tetrakis_hexahedron">tetrakis cube</a>.</p>
<p>Let \(\mathbf{\hat{v}}_0 = [0, 0, 1]\) as before, but \(\mathbf{\hat{v}}_1 = \frac{1}{\sqrt{3}}[1, -1, 1]\), and \(\mathbf{\hat{v}}_2 = \frac{1}{\sqrt{3}}[1, 1, 1]\). Then \(\mathbf{\hat{v}}_0 \cdot \mathbf{\hat{v}}_1 = \mathbf{\hat{v}}_0 \cdot \mathbf{\hat{v}}_2 = \frac{1}{\sqrt{3}}\), \(\mathbf{\hat{v}}_1 \cdot \mathbf{\hat{v}}_2 = \frac{1}{3}\), \(\lvert \mathbf{V}\rvert = \frac{2}{3}\), and \(A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_2) = \frac{\pi}{6}\).</p>
<p>First, here are some expressions involving \(\mathbf{\hat{p}}\). Note that \(\mathbf{\hat{v}}_0 \times \mathbf{\hat{v}}_1 = \frac{1}{\sqrt{3}}[1,1,0]\) and \(\mathbf{\hat{v}}_1 \times \mathbf{\hat{v}}_2 = \frac{2}{3}[-1, 0, 1]\). To avoid some repetition, let \(b = \sqrt{2v_x^2 + v_y^2}\).</p>
\[\begin{split}
\mathbf{\hat{p}} &= \frac{\mathbf{\hat{v}} - (v_z - v_x) \mathbf{\hat{v}}_0}
{b} \\
\mathbf{\hat{v}}_0 \cdot \mathbf{\hat{p}} &= \frac{v_x}
{b} \\
\mathbf{\hat{v}}_1 \cdot \mathbf{\hat{p}} &= \frac{2v_x - v_y}
{\sqrt{3}\, b} \\
|\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}}| &= \frac{v_x + v_y}
{\sqrt{3}\, b} \\
A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}}) &= 2\arctan \frac{v_x + v_y}{
\left(2+\sqrt{3}\right)v_x - v_y + \left(1+\sqrt{3}\right)b}
\end{split}\]
<p>Then, with a bunch of tedious algebra and a couple \(\arctan\) identities, we find that</p>
\[\begin{split}
x &= \sqrt{b \frac{b+v_x}{1+v_z}}\\
y &= x \frac{12}{\pi}\arctan \left(\frac{v_y}{b + 2 v_x}\right)
\end{split}\]
<p>Projections for the other triangles can be found by permuting the vector and negating components of the vector and the result. This projection is the one used in the <a href="https://en.wikipedia.org/wiki/COBE_sky_cube">COBE sky cube</a> scheme. Well, one of them. The projection used in the earlier paper<sup id="fnref:Chan" role="doc-noteref"><a href="#fn:Chan" class="footnote" rel="footnote">7</a></sup> is different than the one in the next paper.<sup id="fnref:ONeill" role="doc-noteref"><a href="#fn:ONeill" class="footnote" rel="footnote">8</a></sup><sup id="fnref:Patt:1" role="doc-noteref"><a href="#fn:Patt" class="footnote" rel="footnote">2</a></sup> The later one is the exact form, which is more common and is the one used here. (Note that the original derivation is for a different face.)</p>
<h1 id="extension-outside-the-triangle">Extension outside the triangle</h1>
<p>Snyder’s equal-area projection can be extended outside the triangle. This isn’t particularly useful in its usual application, but can be nice for analysis.</p>
<p>Only one change to the forward formula is needed, and even that’s optional. As one vertex of a triangle is moved around the sphere, there is a place on the far side where its signed area changes sign with a discontinuity. The placement of this discontinuity can be changed by splitting the triangle \(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}}\) to offset the area. Formula-wise, say we want the discontinuity to lie opposite the midpoint \(\mathbf{\hat{m}}\) between \(\mathbf{\hat{v}}_1\) and \(\mathbf{\hat{v}}_2\). Just replace \(A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{p}})\) in the forward formula with \(A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_m, \mathbf{\hat{p}}) + A(\mathbf{\hat{v}}_0, \mathbf{\hat{v}}_1, \mathbf{\hat{v}}_m)\).</p>
<h1 id="irregular-triangles">Irregular triangles</h1>
<p>Snyder’s paper only looked at regular polygons, which can be divided symmetrically into isosceles triangles. It is possible to divide an irregular spherical triangle into three equal-area triangles, using the <a href="/2021/05/02/spherical-triangle-centers.html">spherical area centroid</a>. These sub-triangles are not isosceles, but the formulas stated above work perfectly fine for irregular triangles.</p>
<h1 id="references">References</h1>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:Snyder" role="doc-endnote">
<p>John P Snyder (1992). An equal-area map projection for polyhedral globes. Cartographica: The International Journal for Geographic Information and Geovisualization, 29(1):10–21. <a href="https://doi.org/10.3138/27H7-8K88-4882-1752">doi://10.3138/27H7-8K88-4882-1752</a> <a href="#fnref:Snyder" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:Snyder:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:Patt" role="doc-endnote">
<p>Fred Patt (1993). Comments on draft WCS standard, in Usenet group sci.astro.fits. <a href="http://www.sai.msu.su/~megera/wiki/relation_featur%E5s/SAI_RVO/SkyPixelization/SphereCube/SphereCube">archive 1</a>, <a href="https://groups.google.com/g/sci.astro.fits/c/KonX3W7m-xY/m/aAPO_dR4NXMJ">archive 2</a> <a href="#fnref:Patt" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:Patt:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:Harrison" role="doc-endnote">
<p>Harrison E., Mahdavi-Amiri A., Samavati F. (2012) Analysis of Inverse Snyder Optimizations. In: Gavrilova M.L., Tan C.J.K. (eds) Transactions on Computational Science XVI. Lecture Notes in Computer Science, vol 7380. Springer. <a href="https://doi.org/10.1007/978-3-642-32663-9_8">doi://10.1007/978-3-642-32663-9_8</a> <a href="#fnref:Harrison" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Voxland" role="doc-endnote">
<p>Snyder, J.P.; Voxland, P.M. (1989). Album of Map Projections, United States Geological Survey Professional Paper. United States Government Printing Office. <a href="https://doi.org/10.3133%2Fpp1453">doi://10.3133/pp1453</a> <a href="#fnref:Voxland" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Lambers" role="doc-endnote">
<p>Lambers, M. (2016) <a href="http://jcgt.org/published/0005/02/01/">Mappings between sphere, disc, and square.</a> Journal of Computer Graphics Techniques (JCGT), vol. 5, no. 2, 1-21 <a href="#fnref:Lambers" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Chiu" role="doc-endnote">
<p>Shirley, P.; Chiu, K. (1997). A low distortion map between disk and square. Journal of graphics tools 2, 3, 45–52. <a href="http://dx.doi.org/10.1080/10867651.1997.10487479">doi://10.1080/10867651.1997.10487479</a> <a href="#fnref:Chiu" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:Chan" role="doc-endnote">
<p>Chan, F.K.; O’Neill, E. M. (1975). <a href="https://ntrl.ntis.gov/NTRL/dashboard/searchResults/titleDetail/ADA010232.xhtml">Feasibility Study of a Quadrilateralized Spherical Cube Earth Data Base</a> (CSC - Computer Sciences Corporation, EPRF Technical Report 2-75) (Technical report). Monterey, California: Environmental Prediction Research Facility. <a href="#fnref:Chan" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:ONeill" role="doc-endnote">
<p>O’Neill, E. M.; Laubscher, R. E. (1976). <a href="https://apps.dtic.mil/dtic/tr/fulltext/u2/a026294.pdf">Extended Studies of a Quadrilateralized Spherical Cube Earth Data Base</a> (Technical report). Monterey, California: Environmental Prediction Research Facility. <a href="#fnref:ONeill" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>John P Snyder, author of many useful articles and books on map projections, created an equal-area projection called (in an aversion of Stigler’s Law) Snyder’s equal-area projection.1 Snyder’s projection was designed for polyhedral globes and maps. The best-known example of a polyhedral map might be Buckminster Fuller’s Dymaxion map, based on an icosahedron. John P Snyder (1992). An equal-area map projection for polyhedral globes. Cartographica: The International Journal for Geographic Information and Geovisualization, 29(1):10–21. doi://10.3138/27H7-8K88-4882-1752 ↩Perspective projections with vectors2021-06-12T00:00:00+00:002021-06-12T00:00:00+00:00https://brsr.github.io/2021/06/12/perspective-vector<p>This is the first post in a series on map projections described using unit vectors. Reference <a href="/2021/05/01/vector-spherical-geometry.html">the introductory article on spherical geometry with vectors</a> if needed.</p>
<p><img src="/assets/images/perspective_projections.svg" alt="Some perspective projections" height="300" align="right" />
This post describes perspective projections – such as <a href="https://en.wikipedia.org/wiki/Orthographic_map_projection">orthographic</a>, <a href="https://en.wikipedia.org/wiki/Stereographic_map_projection">stereographic</a>, and <a href="https://en.wikipedia.org/wiki/Gnomonic_projection">gnomonic</a> – in terms of vectors. By perspective projections, I mean projections that can be described as projecting an object onto a plane using a certain point of perspective. The point of perspective may be outside, inside, or on the surface of the object. A line is drawn from a point on the object through the point of perspective, and where it meets the plane is the projected point. That said, this article may not be the best introduction to the topic: if not familiar with these projections already, I recommend reading the linked pages.</p>
<p>In the following, let \(\mathbf{\hat{v}}\) be a point on the sphere, and \(\mathbf{z}\) be the projected point on the 2d plane. Although some of these projections work with other objects, we’ll limit ourselves to the sphere. Let \(\mathbf{\hat{n}} = [0,0,1]\) be a unit vector pointing towards the north pole. Also let \(\mathbf{Q}\) be a matrix that drops the third component of a vector:</p>
\[\mathbf{Q} = \begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0
\end{bmatrix}\]
<p>Projections where the point of projection is vertical to the plane and projected object, rather than tilted with respect to them, are more common, and this post is limited to those. We’ll use a plane tangent to the unit sphere at the point \(\mathbf{\hat{c}}\): \(\mathbf{\hat{c}} \cdot \mathbf{p} = 1\), where \(\mathbf{p}\) is a point on the plane. Points with \(\mathbf{\hat{c}} \cdot \mathbf{\hat{v}} > 0\) are considered to be on the near side of the object. Note that other derivations may place the sphere and plane elsewhere in space: the difference in the projection is usually just a scaling factor or a sign change.</p>
<p>Derivations are saved for the last section, where they’re performed for the general case.</p>
<h1 id="more-rotations">More rotations</h1>
<p>First, let’s go over a rotation that wasn’t discussed in that introductory article. Often one wants to rotate a frame of reference so that a certain point is in a certain position. Let’s say we want the unit vector \(\mathbf{\hat{c}}\) to align with the z axis. We also need to pick an orientation: typically in map projections one wants north to be up, although if \(\mathbf{\hat{c}}\) is at the north or south pole another choice must be made.</p>
<p>Let \(\mathbf{\hat{a}}\) be the center (or pole) of the great circle passing through \(\mathbf{\hat{c}}\) and the North Pole, such that \(\mathbf{\hat{a}} = \frac{\mathbf{\hat{n}} \times \mathbf{\hat{c}}}{\|\mathbf{\hat{n}} \times \mathbf{\hat{c}}\|}\). Also let \(\mathbf{\hat{b}} = \mathbf{\hat{c}} \times \mathbf{\hat{a}}\). The matrix \(\mathbf{R}\) with rows \(\mathbf{\hat{a}}\), \(\mathbf{\hat{b}}\), and \(\mathbf{\hat{c}}\) transforms the vector \(\mathbf{\hat{a}}\) to \([1,0,0],\) \(\mathbf{\hat{b}}\) to \([0,1,0],\) and \(\mathbf{\hat{c}}\) to \([0,0,1]\). This is a rotation matrix by construction, so its inverse is equal to its transpose.</p>
<p>We can give \(\mathbf{z}\) and \(\mathbf{p}\) a more formal definition now:</p>
\[\begin{split}
\mathbf{z} &= \mathbf{Q} \mathbf{R} \mathbf{p}, \\
\mathbf{p} &= \mathbf{R}^\top [z_1, z_2, 1].
\end{split}\]
<h1 id="orthographic">Orthographic</h1>
<p>The orthographic projection is what an object in space looks like viewed a perspective infinitely far from the object. This can be described as rotating the object as described above, leaving out the component in the direction of \(\mathbf{\hat{c}}\). Let \(\mathbf{R}\) be that rotation matrix, and then</p>
\[\mathbf{z} = \mathbf{Q} \mathbf{R} \mathbf{\hat{v}},\]
<p>This representation of the projection does not depend on the shape of the surface being projected. Anything with a representation as a vector in space can be handled this way: a sphere, an ellipsoid, an irregular lumpy asteroid.</p>
<p>Normally one wishes to only project the near side of the object. With that restriction, the projection transforms a hemisphere centered on \(\mathbf{\hat{c}}\) to a disk in the plane. Without that restriction, the other hemisphere is transformed to the same disk, in reversed orientation.</p>
<p>The inverse projection is fairly straightforward, except that the component discarded by \(\mathbf{Q}\) needs to be determined. For a unit sphere, \(z_3 = \sqrt{1-z_1^2-z_2^2}\) for points the near side. (Note that this is different from what was given in the previous section: the reason will be explained in the derivation.) Then:</p>
\[\mathbf{\hat{v}} = \mathbf{R}^\top [z_1, z_2, z_3].\]
<h1 id="stereographic">Stereographic</h1>
<p>For the stereographic projection, the point of perspective is antipodal to \(\mathbf{\hat{c}}\). The stereographic projection maps the entire sphere to the plane, minus one point, \(\mathbf{\hat{c}}\), which is mapped to infinity. This projection is conformal: it preserves angles locally.</p>
<p>The forward projection formula is as follows. The factor of 2 makes the scale true at the center of the projection.</p>
\[\mathbf{z} = \mathbf{Q} \mathbf{R} \mathbf{\hat{v}} \frac{2}{\mathbf{\hat{c}} \cdot \mathbf{\hat{v}} + 1}\]
<p>The inverse projection is as so:</p>
\[\mathbf{\hat{v}} = \frac{4\mathbf{p} + \mathbf{\hat{c}}\left(1 - \|\mathbf{p}\|^2\right)}{\|\mathbf{p}\|^2 + 3}\]
<p>The stereographic projection can be extended to the ellipsoid by using the <a href="https://en.wikipedia.org/wiki/Latitude#Conformal_latitude">conformal latitude</a>.</p>
<h1 id="gnomonic">Gnomonic</h1>
<p>The gnomonic projection can be thought of as placing a light at the center of a transparent sphere and shining it through onto a plane. It has the special quality that all geodesics on the sphere are transformed in to straight lines in the plane. This is easy to show: great circles are the intersection of a plane with the sphere, while the intersection of a plane with another plane is a line. (This doesn’t hold with an ellipsoid, but can be a useful approximation.)</p>
<p>The forward projection is:</p>
\[\mathbf{z} = \mathbf{Q} \mathbf{R} \frac{\mathbf{\hat{v}}}{\mathbf{\hat{c}} \cdot \mathbf{\hat{v}}}\]
<p>Like the orthographic projection, one generally only wants the near side of the object. If included, the far side of the object appears reversed.</p>
<p>For the inverse, the formula for \(\mathbf{\hat{v}}\) is simple:</p>
\[\mathbf{\hat{v}} = \frac{\mathbf{p}}{\|\mathbf{p}\|}
= \frac{\mathbf{R}^\top [z_1, z_2, 1]}{\|z_1, z_2, 1\|}\]
<h2 id="gnomonic-with-barycentric-coordinates">Gnomonic with barycentric coordinates</h2>
<p>A bit of detour. <a href="https://en.wikipedia.org/wiki/Barycentric_coordinate_system">Barycentric coordinates</a> can be applied for further useful results. Let \(\mathbf{\hat{v}}_1\), \(\mathbf{\hat{v}}_2\), and \(\mathbf{\hat{v}}_3\) be points on the sphere not sharing a great circle, and let \(\mathbf{\hat{c}}\) be the spherical circumcenter of the triangle formed by those points. (See <a href="/2021/05/02/spherical-triangle-centers.html">this post on spherical triangle centers</a> if needed.) Also let \(\mathbf V\) be the matrix whose i-th columns is \(\mathbf{\hat{v}}_i\). Let \(\mathbf \beta\) be the vector of barycentric coordinates, let \(\beta_i\) be its \(i\)th component, and let \(\mathbf \alpha\) and \(\alpha_i\) be defined similarly. Finally, the barycentric coordinates of the point projected in gnomonic projection centered at \(\mathbf{\hat{c}}\) can be found in a two-step process:</p>
\[\begin{split}
\mathbf{\alpha} &= \mathbf{V}^{-1} \mathbf{\hat{v}}, \\
\beta_i &= \frac{\alpha_i}{\sum_i \alpha_i}.
\end{split}\]
<p>Note that the determinant of \(\mathbf V\) can be left out of the matrix inverse: it’ll be cancelled out in the second formula.</p>
<p>The inverse projection is particularly simple:</p>
\[\mathbf{\hat{v}} = \frac{\mathbf{V} \mathbf{\beta}}{\|\ldots\|},\]
<p>and is useful for creating triangular grids on the sphere. In the geodesic dome community, gnomonic projection of a triangular grid is called “method 1”.</p>
<h1 id="general-perspective-projection">General perspective projection</h1>
<p>All three of these projections are specific cases of the general perspective projection. One could project from a point at a similar distance to the globe as a satellite camera is to the Earth. (Or the moon, but the moon is far enough away that you might as well use orthographic projection.)</p>
<p>Restating the assumptions so they’re in one place: let \(\mathbf{\hat{v}}\) be a point on the object being projected \(\mathbf{\hat{c}}\) specifies a plane tangent to the unit sphere: where \(\mathbf{p}\) is a point on the plane, \(\mathbf{\hat{c}} \cdot \mathbf{p} = 1\). \(\mathbf{R}\) is a rotation matrix as defined earlier, and \(\mathbf{Q}\) is the 2x3 matrix defined earlier, so that \(\mathbf{z} = \mathbf{Q} \mathbf{R} \mathbf{p}\) and \(\mathbf{p} = \mathbf{R}^\top [z_1, z_2, 1]\). Finally, let \(k\mathbf{\hat{c}}\) be the point of projection, where \(k\) be a real number indicating how far the point of projection is from the origin. For stereographic, \(k=-1\); for gnomonic, \(k=0\); for orthographic, take the limit as \(k\) approaches positive infinity. (At \(k=1\), the projection is not well-defined.)</p>
<p>For the forward projection, start as so. \(\mathbf{p}\) must lie on the line between \(\mathbf{\hat{v}}\) and \(k\mathbf{\hat{c}}\), so start with linear interpolation:</p>
\[\mathbf{p} = \mathbf{\hat{v}} t + \mathbf{\hat{c}} (1-t).\]
<p>The \(t\) such that \(\mathbf{p}\) satisfies \(\mathbf{\hat{c}} \cdot \mathbf{p} = 1\) is</p>
\[t = \frac{1 - k}{\mathbf{\hat{c}} \cdot \mathbf{\hat{v}} - k}.\]
<p>By definition, \(\mathbf{Q} \mathbf{R} \mathbf{\hat{c}} = [0, 0]\), so the term involving \(\mathbf{\hat{c}}\) can be dropped. Finally, the projected point is</p>
\[\mathbf{z} = \mathbf{Q} \mathbf{R} \mathbf{\hat{v}} \frac{1-k}
{\mathbf{\hat{c}} \cdot \mathbf{\hat{v}} + k}.\]
<p>This can be easily verified to be equal to the specific projections above for their given value of \(k\). (Hint for orthographic: divide the numerator and denominator by \(k\).)</p>
<p>The inverse projection starts similarly: find \(\mathbf{\hat{v}}\) on the line between \(\mathbf{p}\) and \(k\mathbf{\hat{c}}\). Applying linear interpolation, for some real number \(t\),</p>
\[\mathbf{\hat{v}} = \mathbf{p} s + k\mathbf{\hat{c}} (1-s).\]
<p>An assumption about the shape of the object being projected is needed: assume the unit sphere, such that \(\|\mathbf{\hat{v}}\| = 1\). Applying that and solving gives a quadratic in \(s\), with solution:</p>
\[s = \frac{k(k-1)\pm \sqrt{(k-1)(2k-\|p\|^2(k+1))}}{\|p\|^2 + k(k-2)}\]
<p>Use the condition \(\mathbf{\hat{c}} \cdot \mathbf{\hat{v}} > 0\) to choose the sign in the formula. The specific inverse projections for stereographic and gnomonic can be derived from this. When \(k=-1\), \(s=\frac{4}{\|\mathbf{p}\|^2 + 3}\) (or \(s=0\), which is a spurious solution). When \(k=0\), \(s=\pm\frac{1}{\|\mathbf{p}\|}\): the positive solution is the one on the near side of the sphere. For the orthographic projection, however, this quadratic equation does not result in a useful answer in the limit: use the solution given earlier instead.</p>
<details>
<summary><i>Click here for the Python code to generate the image in the introduction.</i></summary>
<pre>
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(9, 4))
patch = mpl.patches.Circle((0,0), radius=1, fill = False, edgecolor='k')
ax.add_artist(patch)
ax.set_aspect('equal')
ax.axis('off')
ax.set_ylim(-1.15, 3.5)
bboxstyle = bbox={'facecolor':'white','alpha':0.75,'edgecolor':'none','pad':1}
v = (1/np.sqrt(2), 1/np.sqrt(2))
ax.scatter(*v, c='k')
ax.plot([1,-1],[1,1], c='k', linestyle='--')
#stereographic
ax.scatter(0, -1, c='blue')
ax.plot([0,-2 + 2*np.sqrt(2)], [-1,1], c='blue')
ax.text(0, -1+0.15, 'Stereographic', ha='center', bbox=bboxstyle)
#gnomonic
ax.scatter(0, 0, c='orange')
ax.plot([0,1], [0,1], c='orange')
ax.text(0, 0.15, 'Gnomonic', ha='center', bbox=bboxstyle)
#general
c = (0, 2)
ax.scatter(*c, c='green')
ax.plot(*zip(c, v), c='green')
ax.text(0, 2.15, 'General', ha='center', bbox=bboxstyle)
#orthographic
#ax.plot((v[0],v[0]),(v[1],3), color='red')
ax.text(0, 3.15, 'Orthographic', ha='center', bbox=bboxstyle)
p1 = mpl.patches.FancyArrowPatch((v[0], v[1]), (v[0], 3.15),
arrowstyle="->", color='red',
mutation_scale=20)
ax.add_artist(p1)
fig.savefig('perspective_projections.svg', bbox_inches = 'tight')
</pre>
</details>This is the first post in a series on map projections described using unit vectors. Reference the introductory article on spherical geometry with vectors if needed.A (sort of) Euclidean triangle on a non-Euclidean surface2021-05-29T00:00:00+00:002021-05-29T00:00:00+00:00https://brsr.github.io/2021/05/29/curved-triangle<p>A question that came up in a math chatroom (yes, I’m the kind of nerd who spends time in math chatrooms): find a “Euclidean” triangle on a non-Euclidean surface. More exactly, find a geodesic triangle on a surface with non-constant <a href="https://en.wikipedia.org/wiki/Gaussian_curvature">Gaussian curvature</a> having the same sum of interior angles as an Euclidean triangle. In <a href="https://en.wikipedia.org/wiki/Spherical_geometry">spherical geometry</a>, where curvature is a positive constant, that sum is larger than 180 degrees, while in <a href="https://en.wikipedia.org/wiki/Hyperbolic_geometry">hyperbolic geometry</a> (negative constant curvature) it is smaller. Intuitively, on a surface with regions of positive and negative curvature, maybe one can find a triangle where it balances out. (The <a href="https://en.wikipedia.org/wiki/Gauss%E2%80%93Bonnet_theorem">Gauss–Bonnet theorem</a> formalizes this notion, although here I won’t use it directly.)</p>
<p>The torus is such a surface: it has positive curvature on the outer region, and negative curvature on the inner region. <a href="http://www.rdrop.com/~half/math/torus/geodesics.xhtml">In general the geodesics of the torus are complicated</a>, but there are some “trivial” geodesics: the inner and outer equators, and the meridians that cut through the torus at right angles to the equators. Let’s see what can be built out of the trivial geodesics.</p>
<p>Consider a geodesic quadrilateral on a ring torus (the usual kind with a hole in the middle), formed by the inner equator, a meridian, the outer equator, and another meridian. Meridians meet equators at right angles, so this quadrilateral has an interior angle of 90 degrees at each vertex. This is a polygon with the angle sum we would expect from the equivalent Euclidean polygon. It’s a rectangle! Sort of. Its edges along the meridians have the same length, but its edges along the equators have different lengths.</p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 45%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/torus/ringtorus1.png" title="Rectangle on a ring torus, cross-section">
<img src="/assets/images/torus/ringtorus1.png" title="Rectangle on a ring torus, cross-section" alt="Rectangle on a ring torus, cross-section" />
<span>Rectangle on a ring torus, cross-section</span>
</a></li>
<li><a href="/assets/images/torus/ringtorus2.png" title="Alternate angle">
<img src="/assets/images/torus/ringtorus2.png" title="Alternate angle" alt="Alternate angle" />
<span>Alternate angle</span>
</a></li>
</ul>
<p>Now consider the same polygon, but on a horn torus instead of a ring torus. The inner equator shrinks into a single point at the origin, and two of the vertices of the rectangle become a single point.</p>
<style>
.image-gallery {overflow: auto; margin-left: -1%!important;}
.image-gallery li {float: left; display: block; margin: 0 0 1% 1%; width: 45%;}
.image-gallery li a {text-align: center; text-decoration: none!important;}
.image-gallery li a span {display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 3px 0;}
.image-gallery li a img {width: 100%; display: block;}
</style>
<ul class="image-gallery" align="center">
<li><a href="/assets/images/torus/horntorus1.png" title="Triangle on a horn torus, cross-section">
<img src="/assets/images/torus/horntorus1.png" title="Triangle on a horn torus, cross-section" alt="Triangle on a horn torus, cross-section" />
<span>Triangle on a horn torus, cross-section</span>
</a></li>
<li><a href="/assets/images/torus/horntorus2.png" title="Alternate angle">
<img src="/assets/images/torus/horntorus2.png" title="Alternate angle" alt="Alternate angle" />
<span>Alternate angle</span>
</a></li>
</ul>
<p>Each of the meridians is tangent to each other at the origin. Thus, the interior angle at that vertex is zero. The other two vertices have right angles at their vertices, as before. Although a triangle with angles of 90, 90, and 0 degrees could not exist in Euclidean geometry, the angle sum is 180 degrees, so it meets the original criteria.</p>
<p>Reactions in the group chat to this “Euclidean” triangle were… let’s say, mixed.</p>
<p><em><a href="https://github.com/brsr/math/blob/master/Curved%20polygon%20on%20a%20torus.ipynb">The Jupyter Notebook used to create the images is available on Github.</a> If downloaded and brought into a local Jupyter session, the 3d plot can be manipulated in interactive mode.</em></p>A question that came up in a math chatroom (yes, I’m the kind of nerd who spends time in math chatrooms): find a “Euclidean” triangle on a non-Euclidean surface. More exactly, find a geodesic triangle on a surface with non-constant Gaussian curvature having the same sum of interior angles as an Euclidean triangle. In spherical geometry, where curvature is a positive constant, that sum is larger than 180 degrees, while in hyperbolic geometry (negative constant curvature) it is smaller. Intuitively, on a surface with regions of positive and negative curvature, maybe one can find a triangle where it balances out. (The Gauss–Bonnet theorem formalizes this notion, although here I won’t use it directly.)