---
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 )
```

<br><br>

# 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)
    }
```




<br><br>

# 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$.


<br><br>

# 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) )
```

<div style="text-align: center">
![circle of arcs around a single arc](`r gif_file`){width=80%}
</div>

```{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.


<br><br>

# 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) )
```

<div style="text-align: center">
![circle of 3 arcs around a pair of arcs](`r gif_file`){width=80%}
</div>

```{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.


<br><br>

# 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) )
```

<div style="text-align: center">
![empty to full circle, and back to empty on the other side](`r gif_file`){width=80%}
</div>
```{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) )
```

<div style="text-align: center">
![empty to full circle, and back to empty on the other side](`r gif_file`){width=80%}
</div>
```{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.

<br><br>

# References

<div id="refs"></div>




<br><br>

# Session Information

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