Continuously varying tube radius
You can take a continuous function and evaluate it at the same points that are also used by ParametricPlot3D
to create the curve. Here is a way to do it:
rr = Reap[
ParametricPlot3D[γ[t], {t, 0, 2 Pi + .01},
ColorFunction ->
Function[{x, y, z, t}, Hue[wColor[Sow[t, "tValues"]]]],
ColorFunctionScaling -> False,
PlotStyle -> Directive[Opacity[.7], CapForm[None]],
PlotRange -> All, Boxed -> False, MaxRecursion -> 0,
PlotPoints -> 100, Axes -> None, Method -> {"TubePoints" -> 30}],
"tValues"];
rr[[1]] /.
Line[pts_, rest___] :> Tube[pts, 0.2 + .1 Sin[rr[[2]]], rest]
Here I chose a Sin[t]
variation of the thickness. To do it, I collect the evaluation points from inside ParametricPlot3D
using Sow
and Reap
.
This list of points is in rr[[2]]
, whereas rr[[1]]
is the plot itself. Then I modify the replacement rule you already had by making the radii of Tube
into a list obtained by applying the desired continuous function to rr[[2]]
.
Another possibility for making a tube with continuously varying width from a space curve is to compute the normal and binormal vectors of the curve with FrenetSerretSystem[]
, which can then be used to assemble the parametric equations of the tube surface. (In general this can fail, but it will work for torus knots).
γ[t_] := {(2 + Cos[3 t]) Cos[2 t], (2 + Cos[3 t]) Sin[2 t], Sin[3 t]};
w[t_] := 2 + Cos[t];
(* normal and binormal vectors *)
{no[t_], bi[t_]} = FrenetSerretSystem[γ[t], t][[-1, {2, 3}]];
ParametricPlot3D[γ[t] + (w[π/2 - t]/10) {Cos[u], Sin[u]}.{no[t], bi[t]},
{t, 0, 2 π}, {u, 0, 2 π}, Axes -> None, Boxed -> False,
ColorFunction -> Function[{x, y, z, t}, Hue[1 - w[t]/3, 1, 1, 0.7]],
ColorFunctionScaling -> False, Mesh -> False, PlotPoints -> {85, 20},
PlotRange -> All]
(Note how I incorporated the opacity information as the fourth parameter in Hue[]
.)
If one finds the Frenet-Serret computations to be too slow, one can use e.g. Bishop frames (see e.g. this and this) instead, but I will not be discussing them further here.