| Title: | Compute Maps and Properties of Polar Zonoids |
|---|---|
| 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, as defined by Chilton and Coxeter (1963) <doi:10.2307/2313051>. 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. |
| Authors: | Glenn Davis [aut, cre] |
| Maintainer: | Glenn Davis <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.3-0 |
| Built: | 2026-05-12 08:25:44 UTC |
| Source: | https://github.com/glenndavis52/polarzonoid |
in 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.
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 in is defined by
real-valued functions on the circle
.
These functions are called the generators of .
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 , we define the
polar zonoid by taking
the generators to be the functions:
These functions are the standard basis of the
trignometric polynomials.
Note that it is convenient for us to put the constant function 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 ,
the zonohedron converges to .
Let be the space of or fewer
disjoint arcs in the circle.
From properties of trigonometric polynomials, it can be
shown that there is a natural homeomorphism
.
For a proof of this, including the definition of the topology
of , see the
User Guide vignette.
Among those properties is the fact that a trigonometric polynomial
of degree has at most roots.
It is clear that
roots define a set of disjoint arcs, in two different ways.
In the special case , we define to be
the 2 improper arcs: the empty arc and the full circle.
We have the inclusions:
Now the boundary is trivially homemorphic
to the sphere .
This is true for any convex body in .
Thus we have homeomorphisms:
where the symbol 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 .
The inverse maps are much more complicated and,
in this version of the package,
are only implemented for .
Since is determined by the single parameter ,
there is no need to have an object for in the package API.
The parameter 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 arcs have endpoints,
so we expect to be a space of dimension .
The fact that it is a simple manifold like
is somewhat surprising.
However, in the simple cases = 0 and 1,
it is easy to visualize;
see the
User Guide
for details.
Glenn Davis <[email protected]>
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.
Test whether a set of arcs are pairwise strictly disjoint.
disjointarcs( arcmat )disjointarcs( arcmat )
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. |
disjointarcs() returns a logical - whether
the given arcs are pairwise strictly disjoint.
If 2 arcs overlap, or are abutting, the function returns FALSE.
plotarcs(),
complementaryarcs(),
arcsintersection(),
arcsunion(),
arcssymmdiff()
Perform Boolean operations on collections of arcs in the circle. Arcs are always considered to be closed, i.e. to contain their endpoints.
complementaryarcs( arcmat ) arcsintersection( arcmat1, arcmat2 ) arcsunion( arcmat1, arcmat2 ) arcssymmdiff( arcmat1, arcmat2 ) arcsdistance( arcmat1, arcmat2 )complementaryarcs( arcmat ) arcsintersection( arcmat1, arcmat2 ) arcsunion( arcmat1, arcmat2 ) arcssymmdiff( arcmat1, arcmat2 ) arcsdistance( arcmat1, arcmat2 )
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. |
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.
plotarcs(),
disjointarcs()
or fewer arcs,
and the boundary of the Polar Zonoid
This section calculates the homeomorphism from
the space of or fewer arcs on the circle,
which is denoted by ,
to the boundary of the polar zonoid, and its inverse.
boundaryfromarcs( arcmat, n=NULL, gapmin=0 ) arcsfromboundary( p, tol=5.e-9 )boundaryfromarcs( arcmat, n=NULL, gapmin=0 ) arcsfromboundary( p, tol=5.e-9 )
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 |
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 denote boundaryfromarcs().
If denotes the full circle,
then = (0,...,0,).
If denotes the empty arc, then = (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 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.
boundaryfromarcs() maps from
to .
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 is the length of p,
then arcsfromboundary()
maps from to .
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 .
In case of error, the function returns NULL.
spherefromarcs(),
arcsfromsphere(),
boundaryfromsphere(),
spherefromboundary(),
complementaryarcs(),
trigpolyroot()
# 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# 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
or fewer arcs,
and the sphere
This section calculates the natural homeomorphism from
the space of or fewer arcs on the circle,
denoted by ,
to the sphere , and its inverse.
spherefromarcs( arcmat, n=NULL, gapmin=0 ) spherefromarcs_plus( arcmat, n=NULL, gapmin=5e-10 ) arcsfromsphere( u )spherefromarcs( arcmat, n=NULL, gapmin=0 ) spherefromarcs_plus( arcmat, n=NULL, gapmin=5e-10 ) arcsfromsphere( u )
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 |
These first and last functions are inverses of each other.
Let be a set of strictly disjoint arcs in ,
and denote the complementary arcs by .
Let
denote the antipodal map.
Let denote spherefromarcs().
Then .
A fancier way to say this:
the antipodal map on
and the complementary map on
are conjugate.
If is the full circle, then = (0,...,0,1).
If is the empty arc, then = (0,...,0,-1).
spherefromarcs() maps from to ;
it returns a unit vector in .
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 is the length of u,
then arcsfromsphere()
maps from to .
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 .
It is simply the composition of boundaryfromsphere()
and arcsfromboundary(),
with a little error checking.
In this version of the package,
valid values for are 1,3,5, and 7.
In case of error, it returns NULL.
boundaryfromarcs(),
spherefromboundary(),
boundaryfromsphere(),
arcsfromboundary(),
complementaryarcs()
and the sphere
This section calculates the homeomorphism from
the space of or fewer arcs on the circle
to the boundary of the polar zonoid, and its inverse.
In this version of the package, must be
0, 1, 2, or 3.
spherefromboundary( p ) boundaryfromsphere( x )spherefromboundary( p ) boundaryfromsphere( x )
p |
an vector of length |
x |
a non-zero vector of length |
spherefromboundary() is simply
central projection of the given point onto the unit sphere
centered at (0,0,...,0,0,),
which is the center of the zonoid.
In this direction there is no restriction on .
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
is 0, 1, 2, or 3.
These two functions are inverses of each other.
spherefromboundary() returns
a unit vector in .
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.
spherefromarcs(),
arcsfromsphere(),
boundaryfromarcs(),
arcsfromboundary()
The function plotarcs() plots a circle
in the plane, with the given arcs overlayed with a thicker line.
plotarcs( arcmat, labels=FALSE, main=NULL, margintext=NA, rad=1, lwd=3, pch=20, cex=1.5, add=FALSE, ... )plotarcs( arcmat, labels=FALSE, main=NULL, margintext=NA, rad=1, lwd=3, pch=20, cex=1.5, add=FALSE, ... )
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 |
plotarcs() returns TRUE or FALSE.
In the
Real Projective Spaces and 3x3 Rotation Matrices
vignette,
it is shown that there is a homeomorphism between ,
the space of balanced configurations of 4 or 2 points on the circle,
and , the space of 3x3 rotation matrices.
These functions implement the homeomorphim and its inverse.
rotationfromarcs( arcmat, tol=5.e-9 ) arcsfromrotation( rotation, tol=1.e-7 ) rotationaroundaxis( axis, theta )rotationfromarcs( arcmat, tol=5.e-9 ) arcsfromrotation( rotation, tol=1.e-7 ) rotationaroundaxis( axis, theta )
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. |
As currently implemented, a 2-point configuration in ,
whose points must be antipodal, maps to a rotation around the x-axis.
The configuration of the 2 points maps to the 3x3 identity matrix.
See the
Real Projective Spaces and 3x3 Rotation Matrices
vignette,
for an animation of this.
rotationfromarcs() maps from to ;
it returns a 3x3 rotation matrix.
arcsfromrotation() maps from to ;
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 .
rotationaroundaxis() returns a 3x3 rotation matrix
which rotates theta radians around the given axis.
In case of error, all these functions return NULL.
boundaryfromarcs(),
spherefromboundary(),
boundaryfromsphere(),
arcsfromboundary(),
complementaryarcs()
Let and be two unit vectors on the unit sphere , that are not antipodal.
The purpose of slerp()is to compute points along the great circle arc from to ,
from user supplied interpolation parameters .
The value produces and generates .
For example to generate n uniformly space points,
set tau = (0:(n-1))/(n-1) .
If tau=NULL, the points are uniformly spaced and their number is computed automatically,
based on the user-supplied parameter thetamax; see Details.
slerp( u0, u1, tau=NULL, thetamax=pi/36 )slerp( u0, u1, tau=NULL, thetamax=pi/36 )
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 |
tau |
a numeric vector of interpolation parameters.
The default is |
thetamax |
the maximum angular step between successive points on the arc.
This value must be positive.
The default corresponds to 5 |
If both thetamax and tau are not NULL,
tau has priority and thetamax is ignored.
When tau=NULL,
the angle step is computed to be
as large as possible and also satisfy .
If the distance between and is ,
the number of points is
and .
The interpolation formula is not linear; it uses the sin() function.
For details see Shoemake.
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.
But if n=1, it returns a plain m-vector.
If tau is not NULL, n=length(tau).
But if length(tau)==0, the function returns NULL.
If tau is NULL (the default),
n = ceiling(theta/thetamax) + 1,
where theta is the angle between u0 and u1.
If u0 and u1 are equal, then n=1.
In case of error, e.g. u0 and u1 are antipodal,
the function returns NULL.
Shoemake, Ken. Animating Rotation with Quaternion Curves. pp. 245-254. SIGGRAPH 1985.
This section calculates the classical support function for convex bodies, for the specific case of the polar zonoid.
support( direction )support( direction )
direction |
an |
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.
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.
boundaryfromarcs(),
trigpolyroot()
Given a trigonometric polynomial of degree ,
defined on the real interval .
The function transforms it to a polynomial
of degree in the standard way,
and then solves that polynomial.
Only the real roots of the original trigonometric polynomial are returned.
trigpolyroot( ablist, tol=.Machine$double.eps^0.5 )trigpolyroot( ablist, tol=.Machine$double.eps^0.5 )
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 |
The given trigonometric polynomial is converted,
using a change of variable and Euler's formula,
to a standard polynomial of degree , see Wikipedia.
This polynomial is solved using base::polyroot().
After the inverse change of variable,
the imaginary roots are removed using tol.
trigpolyroot() returns the real roots in the interval
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
.
If is 0, or all the coefficients are 0, it is an error.
In case of error, the function returns NULL.
Wikipedia. Trigonometric polynomial. https://en.wikipedia.org/wiki/Trigonometric_polynomial
polyroot()