Version: | 0.1-2 |
Date: | 2025-06-10 |
Title: | Compute Maps and Properties of Polar Zonoids |
Depends: | R (≥ 4.0.0) |
Imports: | logger |
Suggests: | knitr, rmarkdown, gifski, flextable, equatags, rgl, zonohedra, microbenchmark, magick, pdftools |
Description: | In each odd dimension is a convex body - the polar zonoid - whose generating functions are trigonometric polynomials. The polar zonoid is a straightforward generalization of the polar zonohedron in dimension 3. The package has some applications of the polar zonoid, including the properties of configuration spaces of arcs on the circle and 3x3 rotation matrices. There is also a root solver for trigonometric polynomials. |
License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
LazyLoad: | no |
NeedsCompilation: | no |
Biarch: | no |
Author: | Glenn Davis [aut, cre] |
Maintainer: | Glenn Davis <gdavis@gluonics.com> |
Repository: | CRAN |
VignetteBuilder: | knitr |
BuildVignettes: | yes |
ByteCompile: | no |
Packaged: | 2025-06-10 22:11:35 UTC; Glenn |
Date/Publication: | 2025-06-13 04:50:07 UTC |
The Polar Zonoid Z_n
in \mathbb{R}^{2n+1}
Description
In each odd dimension is a special convex body - the polar zonoid - which is generated by trigonometric polynomials. The package has some applications of the polar zonoid, including the properties of spaces of arcs on the circle and 3x3 rotation matrices.
Introduction
A zonoid is a special type of convex body, see Bolker.
Among its many properties, a zonoid is centrally symmetric.
A zonoid has many equivalent definitions,
but in this package a zonoid Z
in \mathbb{R}^m
is defined by
m
real-valued functions f_1,f_2,...,f_m
on the circle
\mathbb{S}^1
.
These functions are called the generators of Z
.
When the generators are piecewise constant, one obtains a zonotope.
For the precise definition of a zonoid, see the
User Guide vignette.
For an integer n \ge 0
, we define the
polar zonoid Z_n
by taking
the generators to be the 2n{+}1
functions:
\cos(\theta),\sin(\theta), \cos(2\theta),\sin(2\theta), ... ,\cos(n\theta),\sin(n\theta), 1 ~~~~~~~~ \theta \in [0,2\pi]
These functions are the standard basis of the
trignometric polynomials.
Note that it is convenient for us to put the constant function 1
last,
instead of the usual convention of putting it first.
The polar zonoid is a straighforward generalization of
the polar zonohedron, see Chilton and Coxeter.
In this paper, it is shown that
as the number of sides of the polar zonohedron goes to \infty
,
the zonohedron converges to Z_1 \subseteq \mathbb{R}^3
.
Let A_n
be the space of n
or fewer
disjoint arcs in the circle.
From properties of trigonometric polynomials, it can be
shown that there is a natural homeomorphism
A_n ~~ \rightleftarrows ~~ \partial Z_n
.
For a proof of this, including the definition of the topology
of A_n
, see the
User Guide vignette.
Among those properties is the fact that a trigonometric polynomial
of degree n
has at most 2n
roots.
It is clear that 2n
roots define a set of n
disjoint arcs, in two different ways.
In the special case n=0
, we define A_0
to be
the 2 improper arcs: the empty arc and the full circle.
We have the inclusions:
A_0 \subseteq A_1 \subseteq A_2 \subseteq ... \subseteq A_n
Now the boundary \partial Z_n
is trivially homemorphic
to the sphere \mathbb{S}^{2n}
.
This is true for any convex body in \mathbb{R}^{2n+1}
.
Thus we have homeomorphisms:
A_n ~~ \rightleftarrows ~~ \partial Z_n ~~ \rightleftarrows ~~ \mathbb{S}^{2n}
where the symbol \rightleftarrows
denotes a homeomorphism.
The bulk of the API for this package is the numerical calculation
of these maps.
The maps that go from left to right are straightforward and
implemented for all n
.
The inverse maps are much more complicated and,
in this version of the package,
are only implemented for n = 0,1,2,3
.
Since Z_n
is determined by the single parameter n
,
there is no need to have an object for Z_n
in the package API.
The parameter n
can be inferred from the dimension
of vector and matrix function arguments,
or in some cases can be given explicitly.
As a sanity check, note that n
arcs have 2n
endpoints,
so we expect A_n
to be a space of dimension 2n
.
The fact that it is a simple manifold like \mathbb{S}^{2n}
is somewhat surprising.
However, in the simple cases n
= 0 and 1,
it is easy to visualize;
see the
User Guide
for details.
Author(s)
Glenn Davis <gdavis@gluonics.com>
References
Bolker, Ethan. A Class of Convex Bodies. Transactions of the American Mathematical Society. v. 145. Nov. 1969.
B. L. Chilton and H. S. M. Coxeter. Polar Zonohedra. The American Mathematical Monthly. Vol 70. No. 9. pp. 946-951. 1963.
arc disjointness
Description
Test whether a set of arcs are pairwise strictly disjoint.
Usage
disjointarcs( arcmat )
Arguments
arcmat |
an Nx2 matrix with an arc definition in each row;
so the total number of arcs is N.
The 1st number in the row is the center of the arc,
and the 2nd number is the length of the arc;
both in radians. |
Value
disjointarcs()
returns a logical - whether
the given arcs are pairwise strictly disjoint.
If 2 arcs overlap, or are abutting, the function returns FALSE
.
See Also
plotarcs()
,
complementaryarcs()
,
arcsintersection()
,
arcsunion()
,
arcssymmdiff()
Boolean arc operations, and also the distance between two collections of arcs.
Description
Perform Boolean operations on collections of arcs in the circle. Arcs are always considered to be closed, i.e. to contain their endpoints.
Usage
complementaryarcs( arcmat )
arcsintersection( arcmat1, arcmat2 )
arcsunion( arcmat1, arcmat2 )
arcssymmdiff( arcmat1, arcmat2 )
arcsdistance( arcmat1, arcmat2 )
Arguments
arcmat |
an Nx2 matrix with an arc definition in each row;
so the total number of arcs is N.
The 1st number in the row is the center of the arc,
and the 2nd number is the length of the arc;
both in radians. The given arcs must be strictly disjoint. |
arcmat1 , arcmat2 |
2 matrices that define 2 collections of arcs, as in the previous argument. The number of arcs in each collection are not required to be equal. |
Value
complementaryarcs()
returns
a matrix of the same size, which represents
the closure of the complement of the union of the given arcs,
as a subset of the circle.
The given arcs must be strictly disjoint;
if not the the function logs and error and returns NULL
.
arcsintersection()
, arcsunion()
, and arcssymmdiff()
return
the intersection, union, and symmetric difference of the 2 given arc collections,
respectively.
arcsdistance()
returns the distance between two collections of arcs.
This distance is the sum of the arc lengths of the symmetric difference.
See Also
plotarcs()
,
disjointarcs()
The Homeomorphism between the Space of n
or fewer arcs,
and the boundary of the Polar Zonoid
Description
This section calculates the homeomorphism from
the space of n
or fewer arcs on the circle,
which is denoted by A_n
,
to the boundary of the polar zonoid, and its inverse.
Usage
boundaryfromarcs( arcmat, n=NULL, gapmin=0 )
arcsfromboundary( p, tol=5.e-9 )
Arguments
arcmat |
an Nx2 matrix with an arc definition in each row;
so the total number of arcs is N.
The 1st number in the row is the center of the arc,
and the 2nd number is the length of the arc;
both in radians. |
n |
the given set of arcs is taken to be in The returned vector is in |
gapmin |
the minimum gap between arcs in |
p |
a vector in |
tol |
if the approximate distance from |
Details
In boundaryfromarcs()
, the calculation of the returned point
is a straightforward integration of
trigonometric functions over the arcs.
The last component of the vector is simply the sum of
the arc lengths.
Let h
denote boundaryfromarcs()
.
If s
denotes the full circle,
then h(s)
= (0,...,0,2\pi
).
If \phi
denotes the empty arc, then h(\phi)
= (0,...,0,0).
arcsfromboundary()
first calculates the outward pointing
normal at p
.
In this version of the package, the implicitization of the boundary,
and thus the normal, is only available when N
is 0, 1, 2, or 3.
This normal determines a trigonometric polynomial
whose roots are calculated with trigpolyroot()
.
These roots are the endpoints of the arcs.
These two functions are inverses of each other.
Value
boundaryfromarcs()
maps from A_n
to \mathbb{R}^{2n+1}
.
It returns the computed point on the boundary of the zonoid.
Names are assigned indicating the corresponding term
in the trigonometric polynomial.
In case of error, the function returns NULL
.
If m
is the length of p
,
then arcsfromboundary()
maps from \mathbb{R}^{m}
to A_N
.
It returns an Nx2 matrix defining N arcs as above.
Because p
might be in a substratum of the boundary,
N might be less than expected, which is (m-1)/2
.
In case of error, the function returns NULL
.
See Also
spherefromarcs()
,
arcsfromsphere()
,
boundaryfromsphere()
,
spherefromboundary()
,
complementaryarcs()
,
trigpolyroot()
Examples
# make two disjoint arcs
arcmat = matrix( c(pi/4,pi/2, pi,pi/4), 2, 2, byrow=TRUE ) ; arcmat
## [,1] [,2]
## [1,] 0.7853982 1.5707963
## [2,] 3.1415927 0.7853982
plotarcs( arcmat )
# map to boundary of the zonoid
b = boundaryfromarcs( arcmat ) ; b
## x1 y1 x2 y2 L
## 0.2346331 1.0000000 0.7071068 1.0000000 2.3561945
# map b back to arcs, and compare with original
arcsdistance( arcmat, arcsfromboundary(b) )
## [1] 2.220446e-16
# so the round trip returns to original pair of arcs, up to numerical precision
The Homeomorphism between the Space of n
or fewer arcs,
and the sphere \mathbb{S}^{2n}
Description
This section calculates the natural homeomorphism from
the space of n
or fewer arcs on the circle,
denoted by A_n
,
to the sphere \mathbb{S}^{2n}
, and its inverse.
Usage
spherefromarcs( arcmat, n=NULL, gapmin=0 )
spherefromarcs_plus( arcmat, n=NULL, gapmin=5e-10 )
arcsfromsphere( u )
Arguments
arcmat |
an |
n |
the given set of arcs is taken to be in The returned vector is in |
gapmin |
the minimum gap between arcs in In |
u |
a unit vector in |
Details
These first and last functions are inverses of each other.
Let a
be a set of n
strictly disjoint arcs in A_n
,
and denote the n
complementary arcs by \bar{a}
.
Let \alpha : \mathbb{S}^{2n} \to \mathbb{S}^{2n}
denote the antipodal map.
Let h
denote spherefromarcs()
.
Then h( \bar{a} ) = \alpha( h(a) )
.
A fancier way to say this:
the antipodal map \alpha
on \mathbb{S}^{2n}
and the complementary map a \mapsto \bar{a}
on A_n
are conjugate.
If s
is the full circle, then h(s)
= (0,...,0,1).
If \phi
is the empty arc, then h(\phi)
= (0,...,0,-1).
Value
spherefromarcs()
maps from A_n
to \mathbb{S}^{2n}
;
it returns a unit vector in \mathbb{R}^{2n+1}
.
It is simply the composition of boundaryfromarcs()
and spherefromboundary()
,
with a little error checking.
In case of error, it returns NULL
.
spherefromarcs_plus()
is the same as spherefromarcs()
,
except it returns additional data.
It returns a list with these items:
u |
the same unit vector returned by |
tangent |
a |
normal |
a |
The matrix cbind(u,tangent,normal)
is square.
When n>n0
, the last normal vector is flipped if necessary,
so that the determinant of the square matrix is positive.
If m
is the length of u
,
then arcsfromsphere()
maps from \mathbb{S}^{m-1}
to A_N
.
It returns an Nx2 matrix defining N arcs as above.
Because the space of arcs is stratified,
N might be less than expected, which is (m-1)/2
.
It is simply the composition of boundaryfromsphere()
and arcsfromboundary()
,
with a little error checking.
In this version of the package,
valid values for m
are 1,3,5, and 7.
In case of error, it returns NULL
.
See Also
boundaryfromarcs()
,
spherefromboundary()
,
boundaryfromsphere()
,
arcsfromboundary()
,
complementaryarcs()
The Homeomorphism between the Boundary of the Polar Zonoid
in \mathbb{R}^{2n+1}
and the sphere \mathbb{S}^{2n}
Description
This section calculates the homeomorphism from
the space of n
or fewer arcs on the circle
to the boundary of the polar zonoid, and its inverse.
In this version of the package, n
must be
0, 1, 2, or 3.
Usage
spherefromboundary( p )
boundaryfromsphere( x )
Arguments
p |
an vector of length |
x |
a non-zero vector of length |
Details
spherefromboundary()
is simply
central projection of the given point onto the unit sphere
centered at (0,0,...,0,0,\pi
),
which is the center of the zonoid.
In this direction there is no restriction on n
.
boundaryfromsphere()
is much harder.
One must find the intersection of two objects:
1) the ray based at the center of the zonoid in the direction x
,
and 2) the boundary of the zonoid.
To do this, an implicit formula for the boundary has been
programmed, but only when
n
is 0, 1, 2, or 3.
These two functions are inverses of each other.
Value
spherefromboundary()
returns
a unit vector in \mathbb{S}^{2n}
.
In case of error, the function returns NULL
.
boundaryfromsphere()
returns the computed point on the boundary of the zonoid.
Names are assigned indicating the corresponding term
in the trigonometric polynomial.
In case of error, the function returns NULL
.
See Also
spherefromarcs()
,
arcsfromsphere()
,
boundaryfromarcs()
,
arcsfromboundary()
plot a collection of arcs
Description
The function plotarcs()
plots a circle
in the plane, with the given arcs overlayed with a thicker line.
Usage
plotarcs( arcmat, labels=FALSE, main=NULL, margintext=NA, rad=1,
lwd=3, pch=20, cex=1.5, add=FALSE, ... )
Arguments
arcmat |
an Nx2 matrix with an arc definition in each row;
so the total number of arcs is N.
The 1st number in the row is the center of the arc,
and the 2nd number is the length of the arc;
both in radians. |
labels |
if |
main |
Text to put above the plot, passed to |
margintext |
if not |
rad |
radius of the arcs, which are centered at (0,0).
A smaller radius can be used with |
lwd |
line width of the arcs. The default |
pch |
symbol for the endpoints, see |
cex |
expansion factor for the endpoints, see |
add |
when |
... |
extra arguments for the both the arcs and their endpoints,
passed to both |
Value
plotarcs()
returns TRUE
or FALSE
.
The homeomorphism between balanced configurations and rotation matrices
Description
In the
Real Projective Spaces and 3x3 Rotation Matrices
vignette,
it is shown that there is a homeomorphism between P_4^\pi
,
the space of balanced configurations of 4 or 2 points on the circle,
and \text{SO(3)}
, the space of 3x3 rotation matrices.
These functions implement the homeomorphim and its inverse.
Usage
rotationfromarcs( arcmat, tol=5.e-9 )
arcsfromrotation( rotation, tol=1.e-7 )
rotationaroundaxis( axis, theta )
Arguments
arcmat |
a |
tol |
In |
rotation |
a 3x3 rotation matrix. The numeric 3x3 matrix property is verified, but, in the interest of speed, orthogonality and orientation-preservation is not verified. |
axis |
a non-zero 3-vector defining an oriented axis in |
theta |
an angle in radians. The computed rotation matrix rotates by this angle. |
Details
As currently implemented, a 2-point configuration in P_2^\pi
,
whose points must be antipodal, maps to a rotation around the x-axis.
The configuration of the 2 points (0,\pm 1)
maps to the 3x3 identity matrix.
See the
Real Projective Spaces and 3x3 Rotation Matrices
vignette,
for an animation of this.
Value
rotationfromarcs()
maps from P_4^\pi
to \text{SO(3)}
;
it returns a 3x3 rotation matrix.
arcsfromrotation()
maps from \text{SO(3)}
to P_4^\pi
;
the returned set of arcs (either 1 or 2 of them) is only defined up to complementation.
Since all we want is the endpoints, the ambiguity does not matter.
The total length of the arcs is \pi
.
rotationaroundaxis()
returns a 3x3 rotation matrix
which rotates theta
radians around the given axis
.
In case of error, all these functions return NULL
.
See Also
boundaryfromarcs()
,
spherefromboundary()
,
boundaryfromsphere()
,
arcsfromboundary()
,
complementaryarcs()
Spherical Linear Interpolation (slerp) on the Unit Sphere
Description
Let u_0
and u_1
be two unit vectors on the unit sphere \mathbb{S}^{m-1}
, that are not antipodal.
The primary purpose of slerp()
is to compute uniformly spaced
points along the great circle arc from u_0
to u_1
.
The angle step \Delta \theta
is computed to be
as large as possible and also satisfy \Delta \theta \le \theta_{max}
,
where \theta_{max}
is a positive user-given parameter.
If the distance between u_0
and u_1
is \theta
, then
\Delta \theta = \theta / \text{ceiling}( \theta / \theta_{max})
.
The secondary purpose is to compute points on the great circle arc
from user supplied interpolation parameters \tau
= a numeric
vector with values typically in [0,1].
The value 0 generates u_0
and 1 generates u_1
.
For example to generate n
uniformly space points,
set \tau
= (0:(n-1))/(n-1)
.
Usage
slerp( u0, u1, thetamax=pi/36, tau=NULL )
Arguments
u0 , u1 |
numeric vectors with same length (verified) and unit length (not verified).
If they are antipodal, the great circle arc is undefined and the
function returns |
thetamax |
the maximum angular step between successive points on the arc.
This value must be positive.
The default corresponds to 5 |
tau |
a numeric vector of interpolation parameters.
The default is |
Details
If both thetamax
and tau
are not NULL
,
tau
has priority and thetamax
is ignored.
The interpolation formula uses the sin()
function.
For details see Shoemake.
Value
slerp()
returns an n x m
matrix with computed points
in the rows.
n
is the number of points, and
m
is the length of u0
and u1
.
When using thetamax
,
n = theta / ceiling(theta/thetamax) + 1
,
where theta
is the angle between u0
and u1
.
Buf if u0
and u1
are equal, then n=1
.
When using tau
, n=length(tau)
.
But if tau
is empty, the function returns NULL
.
In case of error, e.g. u0
and u1
are antipodal,
the function returns NULL
.
References
Shoemake, Ken. Animating Rotation with Quaternion Curves. pp. 245-254. SIGGRAPH 1985.
The Support Function for the Polar Zonoid in \mathbb{R}^{2n+1}
Description
This section calculates the classical support function for convex bodies, for the specific case of the polar zonoid.
Usage
support( direction )
Arguments
direction |
an |
Details
Each direction is converted to a non-zero trignometric polynomial.
The roots are computed using trigpolyroot()
and the the roots
are converted to arcs, and thus arcs
.
The function boundaryfromarcs()
is then used to compute
argmax
, and then value
.
Value
support()
returns a data frame with R
rows and these columns:
direction |
the given matrix of directions |
value |
the value of the support function of the zonoid, in the given direction |
argmax |
the point on the boundary of the zonoid where the maximum is taken |
arcs |
the number of arcs for |
In case of error, the function returns NULL
.
See Also
boundaryfromarcs()
,
trigpolyroot()
compute roots of a trigonometric polynomial
Description
Given a trigonometric polynomial of degree n
,
defined on the real interval [0,2\pi]
.
The function transforms it to a polynomial
of degree 2n
in the standard way,
and then solves that polynomial.
Only the real roots of the original trigonometric polynomial are returned.
Usage
trigpolyroot( ablist, tol=.Machine$double.eps^0.5 )
Arguments
ablist |
a list with 3 items
| ||||||
tol |
tolerance for the imaginary part; if the absolute value of the
imaginary part of the root is less than or equal to |
Details
The given trigonometric polynomial is converted,
using a change of variable and Euler's formula,
to a standard polynomial of degree 2n
, see Wikipedia.
This polynomial is solved using base::polyroot()
.
After the inverse change of variable,
the imaginary roots are removed using tol
.
Value
trigpolyroot()
returns the real roots in the interval
[0,2\pi)
and in increasing order (as a numeric vector).
There may be duplicates, which correspond to multiple roots.
It is up to the user to handle multiple roots.
The number of roots returned is always even, and in the set
\{ 0,2,4,..,2n \}
.
If n
is 0, or all the coefficients are 0, it is an error.
In case of error, the function returns NULL
.
Source
Wikipedia. Trigonometric polynomial. https://en.wikipedia.org/wiki/Trigonometric_polynomial
See Also
polyroot()