I have a graphic picture which is an annulus and I need to map it conformally onto a cylinder.
The real math problem is to map a punched plane onto a cylinder conformally. I am given a part of a plane near the origin. The origin is removed. So, I take a bigger disc around the origin and remove another tiny disc around the origin. Then I am left with the annulus. Now I want to map this annulus onto a cylinder.
I tried Texture but the best I could do is to wrap a square around a cylinder. I ether need to cut the annulus, map it conformally onto a square first and then use Texture. Here I got stuck with conformal mapping. How to map conformally a cut annulus on a square?
Is there a better way how to do this mapping/texture directly?
Thank you!
-
$\begingroup$ Can you post the code you've tried? $\endgroup$– aardvark2012Commented Oct 5, 2017 at 9:58
1 Answer
Here is what I tried to get a conformal parameterization from an annulus to a cylinder with Mathematica.
First I make an ansatz, transforming polar coordinates to cylindrical ones, where I use the offset function h
in the axial direction as degree of freedom.
Off[Part::partd]
zz = {z[[1]], z[[2]]};
f = z \[Function] Evaluate[Module[{r, \[Phi]},
{r, \[Phi]} = ToPolarCoordinates[zz];
{R Cos[\[Phi]], R Sin[\[Phi]], h[r]}]
];
Next, I compute the Riemannian metric that is generated via pullback along the ansatz f
.
metric = D[f[zz], {zz, 1}]\[Transpose].D[f[zz], {zz, 1}] /. Power[zz.zz, p_] :> r^(2 p) // Simplify;
The map f
is conformal if and only if metric
is a diagonal matrix with both entries on the diagonal being equal. Hence, I try to find h
by letting the off-diagonal entries vanish (note that metric
is symmetric, so that metric[[1, 2]]
and metric[[2, 1]]
coincide):
sol = Solve[metric[[1, 2]] == 0 /. z[[1]]^2 -> r^2 - z[[2]]^2, Derivative[1][h][r]];
dsol = DSolve[Equal @@ #, h[r], r] & /@ sol[[All, 1]] /. r -> Sqrt[z[[1]]^2 + z[[2]]^2];
f1 = z \[Function] Evaluate[f[zz] /. dsol[[1, 1]] // Simplify]
f2 = z \[Function] Evaluate[f[zz] /. dsol[[2, 1]] // Simplify]
(* Function[z, {(R z[[1]])/Sqrt[z[[1]]^2 + z[[2]]^2], (R z[[2]])/Sqrt[z[[1]]^2 + z[[2]]^2], C[1] - 1/2 R Log[z[[1]]^2 + z[[2]]^2]}] *)
(* Function[z, {(R z[[1]])/Sqrt[z[[1]]^2 + z[[2]]^2], (R z[[2]])/Sqrt[z[[1]]^2 + z[[2]]^2], C[1] + 1/2 R Log[z[[1]]^2 + z[[2]]^2]}] *)
Aha, this seems to work. Let's test the results:
D[f1[zz], {zz, 1}]\[Transpose].D[f1[zz], {zz, 1}] // Simplify
D[f2[zz], {zz, 1}]\[Transpose].D[f2[zz], {zz, 1}] // Simplify
(* {{R^2/(z[[1]]^2 + z[[2]]^2), 0}, {0, R^2/(z[[1]]^2 + z[[2]]^2)}} *)
(* {{R^2/(z[[1]]^2 + z[[2]]^2), 0}, {0, R^2/(z[[1]]^2 + z[[2]]^2)}} *)
That's it! Note that we have only one integration constant C[1]
. This tells us that the ratio of inner to outer radius of the annulus must correspond in some way to the aspect ratio of the cylinder.
This is how it can be used in practice:
texcoordfun = X \[Function] Evaluate[{1/2, 1/2} + 1/11 zz /. Solve[f1[zz] == {X[[1]], X[[2]], X[[3]]}, {z[[1]], z[[2]], R}][[4]] /. C[1] -> 1];
tex = Texture[ExampleData[{"TestImage", "Apples"}]];
gr = RevolutionPlot3D[{1, 0, t}, {t, 0, 1}, Mesh -> None, PlotStyle -> White];
gc3D = Cases[gr, _GraphicsComplex][[1]];
texcoords = texcoordfun /@ gc3D[[1]];
AppendTo[gc3D, VertexTextureCoordinates -> texcoords];
gc2D = gc3D;
gc2D[[1]] = texcoords;
Graphics[{tex, gc2D}]
Graphics3D[{tex, gc3D}]
-
$\begingroup$ Thank you so much! It works! I'll post my attempt to write such a code and ask few more details later. $\endgroup$– MashaCommented Oct 6, 2017 at 18:45