Parametric surfaces

Manifolds.ParametricSurface โ€” Type
ParametricSurface{TMP<:AbstractManifold{โ„},TE<:Euclidean,TF,TIF,TDF} <: AbstractDecoratorManifold{โ„}

Surface in โ„โฟ described by a parametric function f defined on a parameter space M_param. The embedding โ„โฟ is described by a Euclidean manifold M_embed. The metric is the restriction of the Euclidean metric to the surface.

More precisely, the surface is the image

\[\mathcal M = \bigl\{f(u) \mid u \in \mathcal M_{\mathrm{param}}\bigr\} \subseteq \mathbb R^n,\]

and its Riemannian metric is induced by the Euclidean inner product,

\[g_u(\xi, \eta) = \left\langle \mathrm Df(u)[\xi], \mathrm Df(u)[\eta]\right\rangle.\]

The functions f!, inverse_f!, and jacobian_f! should be defined in-place. They map parameters p to embedded points q, embedded points to parameters, and parameters to the Jacobian of f, respectively.

Note that inverse_f! is required to accept any point in the embedding space, not just points on the surface. It should return the parameters of the closest point on the surface to the input point, i.e. parameters satisfying

\[f\bigl(\operatorname{inverse\_f}(q)\bigr) \in \underset{x \in \mathcal M}{\arg\min}\ \lVert q - x \rVert.\]

Constructor

ParametricSurface(M_param, M_embed, f!, inverse_f!, jacobian_f!)
source
Manifolds.gaussian_curvature โ€” Method
gaussian_curvature(M::ParametricSurface, p; kwargs...)

Return the Gaussian curvature of M at embedded point p, computed in its forwarded atlas.

For a surface, the Gaussian curvature is half of the Ricci scalar,

\[K(p) = \tfrac{1}{2}\operatorname{Ric}(p).\]

source
ManifoldsBase.check_point โ€” Method
check_point(M::ParametricSurface, q; kwargs...)

Check whether the embedded point q lies on M by applying the inverse parametrization and reconstructing it with f!.

The check verifies that $q \approx f(\operatorname{inverse\_f}(q))$.

source
ManifoldsBase.check_vector โ€” Method
check_vector(M::ParametricSurface, p, X; atol::Real=sqrt(eps(float(number_eltype(p)))), kwargs...)

Check whether X is tangent to the parametric surface M at embedded point p. Computes Jacobian of the parametrization at the parameters corresponding to p and checks whether the difference between X and its projection onto the tangent space is smaller than atol.

At $p = f(u)$, the tangent space is

\[T_p\mathcal M = \operatorname{range}\bigl(\mathrm Df(u)\bigr).\]

source
ManifoldsBase.project! โ€” Method
project!(M::ParametricSurface, Y, p, X)

Project the ambient vector X orthogonally onto the tangent space of M at p and store it in Y.

For $p = f(u)$ and $J = \mathrm Df(u)$, this computes

\[Y = J\bigl(J \backslash X\bigr),\]

where $J \backslash X$ denotes the least-squares solution.

source
ManifoldsBase.project! โ€” Method
project!(M::ParametricSurface, q, p)

Project p onto M by applying the inverse parametrization followed by f! and store the result in q. Thus, $q = f(\operatorname{inverse\_f}(p))$ is a closest point on the surface.

source

Example

The Mรถbius band is parametrized by a strip coordinate $u \in [-w, w]$ and an angle $\theta \in \mathbb S^1$. Its parameter space is therefore the product of a Hyperrectangle and a Circle.

using Manifolds, Plots, RecursiveArrayTools, ForwardDiffhalf_width = 0.35M_param = ProductManifold(Hyperrectangle([-half_width], [half_width]), Circle())M_embed = Euclidean(3)function mobius!(v, p::ArrayPartition)    u, ฮธ = p.x[1][1], p.x[2][]    v .= [        (1 + u * cos(ฮธ / 2)) * cos(ฮธ),        (1 + u * cos(ฮธ / 2)) * sin(ฮธ),        u * sin(ฮธ / 2),    ]    return vendfunction inverse_mobius!(p::ArrayPartition, u)    ฮธ = atan(u[2], u[1])    p.x[1][1] =        (u[1] - cos(ฮธ)) * cos(ฮธ / 2) * cos(ฮธ) +        (u[2] - sin(ฮธ)) * cos(ฮธ / 2) * sin(ฮธ) + u[3] * sin(ฮธ / 2)    p.x[2][] = ฮธ    return pendfunction jacobian_mobius!(J, p::ArrayPartition)    ForwardDiff.jacobian!(J, v -> mobius!(Vector{eltype(x)}(undef, manifold_dimension(M_embed)), v), p)    return JendM = ParametricSurface(M_param, M_embed, mobius!, inverse_mobius!, jacobian_mobius!)
ParametricSurface{ProductManifold{โ„, Tuple{Hyperrectangle{Vector{Float64}}, Circle{โ„}}}, Euclidean{โ„, ManifoldsBase.TypeParameter{Tuple{3}}}, typeof(Main.var"Main".mobius!), typeof(Main.var"Main".inverse_mobius!), typeof(Main.var"Main".jacobian_mobius!)}(ProductManifold(Hyperrectangle([-0.35], [0.35]), Circle(โ„)), Euclidean(3; field=โ„), Main.var"Main".mobius!, Main.var"Main".inverse_mobius!, Main.var"Main".jacobian_mobius!)

Sampling its parametrization can be used to produce a three-dimensional view of the band.

strip_coordinates = range(-half_width, half_width; length = 41)angles = range(-ฯ€, ฯ€; length = 181)xyz = [mobius!(zeros(3), ArrayPartition([u], [ฮธ])) for u in strip_coordinates, ฮธ in angles]x = [p[1] for p in xyz]y = [p[2] for p in xyz]z = [p[3] for p in xyz]
41ร—181 Matrix{Float64}:
  0.35     0.349947   0.349787   0.34952   โ€ฆ  -0.349787  -0.349947  -0.35
  0.3325   0.332449   0.332297   0.332044     -0.332297  -0.332449  -0.3325
  0.315    0.314952   0.314808   0.314568     -0.314808  -0.314952  -0.315
  0.2975   0.297455   0.297319   0.297092     -0.297319  -0.297455  -0.2975
  0.28     0.279957   0.279829   0.279616     -0.279829  -0.279957  -0.28
  0.2625   0.26246    0.26234    0.26214   โ€ฆ  -0.26234   -0.26246   -0.2625
  0.245    0.244963   0.244851   0.244664     -0.244851  -0.244963  -0.245
  0.2275   0.227465   0.227361   0.227188     -0.227361  -0.227465  -0.2275
  0.21     0.209968   0.209872   0.209712     -0.209872  -0.209968  -0.21
  0.1925   0.192471   0.192383   0.192236     -0.192383  -0.192471  -0.1925
  โ‹ฎ                                        โ‹ฑ                         โ‹ฎ
 -0.21    -0.209968  -0.209872  -0.209712      0.209872   0.209968   0.21
 -0.2275  -0.227465  -0.227361  -0.227188      0.227361   0.227465   0.2275
 -0.245   -0.244963  -0.244851  -0.244664      0.244851   0.244963   0.245
 -0.2625  -0.26246   -0.26234   -0.26214   โ€ฆ   0.26234    0.26246    0.2625
 -0.28    -0.279957  -0.279829  -0.279616      0.279829   0.279957   0.28
 -0.2975  -0.297455  -0.297319  -0.297092      0.297319   0.297455   0.2975
 -0.315   -0.314952  -0.314808  -0.314568      0.314808   0.314952   0.315
 -0.3325  -0.332449  -0.332297  -0.332044      0.332297   0.332449   0.3325
 -0.35    -0.349947  -0.349787  -0.34952   โ€ฆ   0.349787   0.349947   0.35

Which can then be visualized using for example GLMakie.jl: GLMakie.surface(x, y, z).

All the usual tools still work as in the embedded torus example.

Internal docs