--- title: "Paths in the Space of Arcs" author: "Glenn Davis" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: toc: true toc_depth: 2 number_sections: false bibliography: bibliography.bib # csl: iso690-numeric-brackets-cs.csl csl: personal.csl # csl: institute-of-mathematical-statistics.csl # csl: transactions-on-mathematical-software.csl vignette: > %\VignetteIndexEntry{Paths in the Space of Arcs} %\VignetteEngine{knitr::rmarkdown} --- ```{css, echo=FALSE} body { max-width: 725px; /* make wider, default is 700px */ } h1{ font-size: 20pt; /* make the level 1 headers smaller */ } ``` ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) old_opt = options( width=144 ) ```

# Introduction ```{r, echo=TRUE, message=FALSE} library(polarzonoid) ``` In the [User Guide](../doc/polarzonoid-guide.html) vignette it is shown that there is are homeomorphisms \begin{equation} A_n ~~ \longleftrightarrow ~~ \partial Z_n ~~ \longleftrightarrow ~~ \mathbb{S}^{2n} \end{equation} where $A_n$ is the space of $n$ or fewer pairwise disjoint arcs in the circle, and $Z_n$ is the polar zonoid in $\mathbb{R}^{2n+1}$. In this vignette, we take some easily-defined paths in the sphere $\mathbb{S}^{2n}$, compute the corresponding paths in the space of arcs $A_n$, and display those paths as animated GIF plots. We make these plots with help of the package **gifski** and this function: ```{r, echo=TRUE, message=FALSE} GIFfromarclist <- function( arclist, arcmat, index=1L, fps=5, vpsize=c(480,512) ) { require( 'gifski' ) # make temp folder pathtemp = tempdir() # "./figs" ; if( ! file.exists(pathtemp) ) dir.create(pathtemp) count = length( arclist ) namevec = names( arclist ) for( k in 1:count ) { filename = sprintf( "%s/plot%03d.png", pathtemp, k ) png( filename=filename, width=vpsize[1], height=vpsize[2], units = "px" ) u = spherefromarcs( arclist[[k]] ) plotarcs( arclist[[k]], labels=FALSE, margintext=namevec[k] ) plotarcs( arcmat, labels=FALSE, rad=0.95, col='blue', lwd=1, add=TRUE ) dev.off() } pathvec = dir( pathtemp, pattern="png$", full=T ) gif_file = sprintf( "%s/animation%g.gif", pathtemp, index ) out = gifski( pathvec, gif_file=gif_file, delay=1/fps, progress=F, width=vpsize[1], height=vpsize[2] ) res = file.remove( pathvec ) # cleanup the .PNG files, leaving just the .GIF return(out) } ```

# The Tubular Neighborhood of $A_n \subseteq A_{n+1}$ $A_n$ is a _stratum_ in $A_{n+1}$ and there is a _tubular neighborhood_ of $A_n$ in $A_{n+1}$. Since the codimension is 2, the fiber of a point $a \in A_n$ in the neighborhood is an open 2-disk $\text{int}(D^2)$. The boundary of the 2-disk is a circle, which we think of this circle as a closed path of points at a small and equal distance from $a$. We can compute this circle by mapping $a$ to $\mathbb{S}^{2n+2}$ using the homeomorphism $A_{n+1} ~ \rightleftarrows ~ \mathbb{S}^{2n+2}$, computing the circle in $\mathbb{S}^{2n+2}$, and then mapping back to $A_{n+1}$ using the inverse homeomorphism. The function we will use is: ```{r, echo=TRUE, message=FALSE} circleofarcs <- function( arcmat, rad=0.1, count=180 ) { res = spherefromarcs_plus( arcmat, n=nrow(arcmat)+1L ) out = vector( count, mode='list' ) namevec = character( count ) for( i in 1:count ) { theta = 2*pi * (i-1)/count # theta is in radians, starting at 0 u = res$u + rad * ( cos(theta)*res$normal[ ,1] + sin(theta)*res$normal[ ,2] ) out[[i]] = arcsfromsphere( u ) # u is automatically unitized namevec[i] = sprintf( "i = %d", i ) } names(out) = namevec return( out ) } ``` The case of $n{=}0$ is easy to visualize. The space $A_0$ is 2 points, which map to the "poles" of the sphere $\mathbb{S}^2$. The empty arc maps to the "south" and the full circle maps to the "north" Around each pole is a small circle. For the "south pole" it is a circle of tiny arcs, almost empty. For the "north pole" it is a circle of very large arcs, almost the full circle. In both cases, the length of the arcs is constant, while the center loops around $\mathbb{S}^1$.

# A Circle of Arcs in $A_2$ around a Single Arc in $A_1$ The goal of this section is to take a single arc $a \in A_1$ and plot the 2 arcs in $A_2$ that circle around $a$. ```{r, echo=TRUE, message=FALSE, warning=TRUE, fig.cap='caption', fig.keep='last', fig.show='hide', cache=FALSE } # arcmat1 is a single semicircle centered at (1,0) arcmat1 = matrix( c(0,pi), nrow=1, ncol=2 ) circle = circleofarcs( arcmat1, count=90 ) gif_file = GIFfromarclist( circle, arcmat1, index=1, vpsize=c(480,480) ) ```
![circle of arcs around a single arc](`r gif_file`){width=80%}
```{r, echo=FALSE, message=TRUE, warning=TRUE } unlink( dirname(gif_file) ) ``` The original arc is drawn in blue, and shrunken a little so it does not overlap with the nearby pair of arcs.

# A Circle of Arcs in $A_3$ around Two Arcs in $A_2$ This section is the same as the previous one, except we bump up the complexity. Now $a \in A_2$ is a pair of arcs, and we plot the 3 arcs in $A_3$ that circle around $a$. ```{r, echo=TRUE, message=FALSE, warning=TRUE, fig.cap='caption', fig.keep='last', fig.show='hide', cache=FALSE } # arcmat2 is: an arc filling quadrant #1, plus an arc filling quadrant #3 arcmat2 = matrix( c((1/4)*pi,pi/2, (5/4)*pi,pi/2), nrow=2, ncol=2, byrow=TRUE ) circle = circleofarcs( arcmat2, count=90 ) gif_file = GIFfromarclist( circle, arcmat2, index=2, vpsize=c(480,480) ) ```
![circle of 3 arcs around a pair of arcs](`r gif_file`){width=80%}
```{r, echo=FALSE, message=TRUE, warning=TRUE } unlink( dirname(gif_file) ) ``` The original pair of arcs are drawn in blue, and shrunken a little so they does not overlap with the nearby triple of arcs.

# Empty Arc to Full Circle, and Back Again In this one, the path in the sphere starts at the "south pole", goes up through an arbitrary point along a great semicircle to the antipodal "north pole", and then down the other side. The full path is a great circle, and is pieced together using the function `slerp()` (spherical linear interpolation) from @Shoemake1985. ```{r, echo=TRUE, message=FALSE} poletopole <- function( arcmat, thetamax=pi/36, n=NULL ) { u = spherefromarcs( arcmat, n=n ) # make south and north poles m = length(u) south = c( rep(0,m-1), -1 ) ; north = -south path1 = slerp( south, u, thetamax=thetamax ) # from "south pole" to u path2 = slerp( u, north, thetamax=thetamax ) # from u to "north pole" path = rbind( path1, path2 ) # concatenate the 2 paths path = rbind( path, -path ) # back down the other side to south pole again count = nrow(path) out = vector( count, mode='list' ) for( i in 1:count ) out[[i]] = arcsfromsphere( path[i, ] ) names(out) = sprintf( "y_%d = %.3f", m, path[ ,m] ) return( out ) } ``` ```{r, echo=TRUE, message=FALSE, warning=TRUE, fig.cap='caption', fig.keep='last', fig.show='hide', cache=FALSE } # arcmat3 is 3 arcs of different lengths arcmat3 = matrix( c(0.375,0.75, 2.3,1.1, 4.6,2.8), ncol=2, byrow=TRUE ) arclist = poletopole( arcmat3 ) gif_file = GIFfromarclist( arclist, arcmat3, index=3, fps=2, vpsize=c(480,480) ) ```
![empty to full circle, and back to empty on the other side](`r gif_file`){width=80%}
```{r, echo=FALSE, message=TRUE, warning=TRUE } unlink( dirname(gif_file) ) ``` The defining arcs are drawn in blue, and shrunken a little so they do not overlap with the arcs along the path. Note that at each step, there are 3 arcs, except at the poles, i.e. the empty arc and the full circle. But it is easy to make an example where the number of arcs is **not** a constant. ```{r, echo=TRUE, message=TRUE, warning=TRUE, fig.cap='caption', fig.keep='last', fig.show='hide', cache=FALSE } # arcmat1 is a single arc, but it splits into 3 arcs on either side of the path from pole to pole arcmat1 = matrix( c(1.5,2.9), ncol=2, byrow=TRUE ) arclist = poletopole( arcmat1, n=3 ) gif_file = GIFfromarclist( arclist, arcmat1, index=4, fps=2, vpsize=c(480,480) ) ```
![empty to full circle, and back to empty on the other side](`r gif_file`){width=80%}
```{r, echo=FALSE, message=TRUE, warning=TRUE } unlink( dirname(gif_file) ) ``` The defining arc is drawn in blue, and shrunken a little so it does not overlap with the arcs along the path.

# References


# Session Information This document was prepared `r format(Sys.Date(), "%a %b %d, %Y")` with the following configuration:
```{r, echo=FALSE, results='asis'}
options(old_opt)
sessionInfo()
```