I'm writing my senior thesis on the theory generic flows on compact surfaces. This is a beautiful geometric subject, and I want beautiful visualizations to match. Here is my strategy:
Step 1: Given an immersed submanifold $M\subseteq\mathbb R^3$, a parametrization $F:\Omega\subseteq\mathbb R^2\to M$, and a vector field $X$ on $M$, we form the pullback vector field $\tilde X$ on $\Omega$ and draw its phase portrait using LineIntegralConvolutionPlot
.
Step 2: Now we use the phase portrait generated in Step 1 to create a texture, and apply this texture to the ParametricPlot3D
of $F$.
Here's an example of a flow on Boy's surface (smooth immersion of $\mathbb RP^2$ into $\mathbb R^3$):
(* some setup *)
w = u+I*v;
gx = -1.5Im[w (1-w^4)/(w^6+Sqrt[5]w^3-1)];
gy = -1.5Re[w (1+w^4)/(w^6+Sqrt[5]w^3-1)];
gz = Im[(1+w^6)/(w^6+Sqrt[5]w^3-1)]-0.5;
(* parametrization of surface *)
surf = {gx,gy,gz}/(gx^2+gy^2+gz^2);
(* domain of parametrization *)
dom = Disk[{0,0},1];
(* vector field *)
vfield = {(1-u^2-v^2)Cos[9u^2+2v],(1-u^2-v^2)(3v-9u^2)};
(* Generate Texture *)
splot = LineIntegralConvolutionPlot[
{vfield,{"noise",2000,2000}},{u,-1,1},{v,-1,1},
ColorFunction->"BeachColors",LightingAngle->0,LineIntegralConvolutionScale->3,
Frame->False,ImageSize->2000
];
img = Image[Show[splot,Frame->False,PlotRangePadding->None],ImageSize->2000];
mask = Image[Graphics[{White,dom},Background->Black,PlotRangePadding->None],ImageSize->2000];
tex = SetAlphaChannel[img,mask]//Image
(* Plot the Surface *)
ParametricPlot3D[
surf,{u,v}\[Element]dom,
PlotStyle->Texture[tex],PlotPoints->200,
Boxed->False,Axes->False,Mesh->None,
Lighting->"Accent"
]
Result:
Pretty sexy if I do say so...
However, a problem arises when I follow the same strategy on other surfaces. For example, here is a simple linear flow on the torus:
Along $F(\partial\Omega)$, the streamlines do not line up because we have simply wrapped a rectangular texture around the torus, instead of constructing the streamlines intrinsically on the torus.
My question is: How can I avoid this kind artifact of texture wrapping?
Possible solutions:
I thought of adding multiple overlapping textures at 50% opacity so that the artifacts become less obvious. However, such an approach doesn't actually remove artifacts; it just makes them less obvious. This is simple for the torus, where different parametrizations are easy to come by (just translate each coordinate by $\pi$). On other surfaces (such as Boy's surface) they are much harder to generate.
The ideal solution would be to adapt the code for
LineIntegralConvolutionPlot
so it can be used directly on surfaces. Does anyone know how to do this?
Any suggestions are appreciated!
Edit: In response to user2432923; linear flow on the torus is generated by a smooth (infinitely differentiable) vector field on the torus and so there is no issue of non-differentiability at $F(\partial\Omega)$. As you can see from the picture, the stream lines continue across the boundary, but change color, giving the illusion of a discontinuity. Henrik Schumacher is also correct that simple considerations of periodicity will not solve the issue on other surfaces, e.g., on the nonorientable surface of genus 2: