k[a_, b_, t_] := a + (b - a)*t^3
f[u_, v_] := {(1 + v/2 Cos[u/2]) Cos[u], (1 + v/2 Cos[u/2]) Sin[u],
v/2 Sin[u/2]}
a = 60; (*frame count*)
borderWidth = -BorderDimensions[
ParametricPlot3D[f[u, v], {u, 0, 2 Pi}, {v, -1, 1},
PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-0.5, 0.5}},
Axes -> False, Boxed -> False]
] + 2;
(* generate image *)
mobiusList = Table[ImagePad[Module[{p = 3 (j/a)^2 - 2 (j/a)^3},
Show[
ParametricPlot3D[f[u, v], {u, 0, p*2 Pi}, {v, -1, 1},
ColorFunction ->
Function[{x, y, z, u},
RGBColor[k[0.880722, 0, u*p], 0.611041, k[0.142051, 1, u*p],
1 - (u*p)^3]],
PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-0.5, 0.5}},
Axes -> False, Boxed -> False, MeshFunctions -> {#5 &},
(* add a break in the mesh so that it doesn't overlap the dashed line *)
Mesh -> {{Splice @ Range[-1, 5/8, 1/8], 7/8, 1}},
PlotPoints -> Ceiling[125 j/a]
],
(* custom-bake the v mesh, and highlight the ends *)
Graphics3D[{GrayLevel[0.2],
Table[
Line[{f[2 Pi/16*i, -1], f[2 Pi/16*i, 1]}], {i, 1,
Floor[p*16]}], Thick, Black,
Line[{{0.5, 0, 0}, {1.5, 0, 0}}],
Line[{f[p*2 Pi, -1], f[p*2 Pi, 1]}]
}],
(* solid & dashed outer lines *)
ParametricPlot3D[{f[u, 1], f[u, 3/4]}, {u, 0, p*2 Pi},
ColorFunction ->
Function[{x, y, z, u},
ColorNegate @
RGBColor[k[0.880722, 0, u*p], 0.611041,
k[0.142051, 1, u*p]]],
PlotStyle -> {Automatic, {Thick, Dashed}},
PlotPoints -> Ceiling[100 j/a]]
]], borderWidth], {j, 1, a}];
(* add frame of single line (u = 0) manually, because trying to do a
parametric plot with {u, 0, 0} causes an error *)
PrependTo[mobiusList, ImagePad[Graphics3D[
{Thick, Line[{{0.5, 0, 0}, {1.5, 0, 0}}]},
PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-0.5, 0.5}},
Boxed -> False
], borderWidth]];
(* export, with the first and last frames lengthened *)
Export["mobius.gif", mobiusList,
"DisplayDurations" -> {1, Splice @ ConstantArray[1/15, Length[mobiusList] - 2], 1}]