## Dec 7, 2013

### Frenet Tube

Given a 3D curve $\vec{r}(t) = (x(t), y(t), z(t)), t \in I=[0,1]$,  Tubify[ {x, y, z},  a] turns it into a tube around the curve. The Mathematica Tube[] has similar function (works on lines). The essential thing is to find the unit circle in the normal plane for each point (Shown in Fig. 1). The tangential vector is simply $\vec{\alpha} = \vec{r}'/|\vec{r}'|$, where $\vec{r}' = \mathrm{d} \vec{r}/\mathrm{d}t$. The normal vector is $\vec \beta = \vec{\alpha}' / |\vec{\alpha}'| = \frac{\vec{r}'' |\vec{r}'|^2 - \vec{r}' \vec{r}'\cdot\vec{r}''}{|\vec{r}'| \sqrt{|\vec{r}''|^2 |\vec{r}'|^2 - (\vec{r}'\cdot\vec{r}'')^2} }$. The binormal vector is $\vec{\gamma} = \vec{\alpha} \times \vec{\beta} = \frac{\vec{r}' \times \vec{r}'' }{\sqrt{|\vec{r}''|^2 |\vec{r}'|^2 - (\vec{r}'\cdot\vec{r}'')^2} }$.

 Fig. 1: black, $\vec{\alpha}$, green $\vec{\beta}$, blue $\vec{\gamma}$.

Tubify[{x_, y_, z_}, r_] :=
({x[#1], y[#1], z[#1]}
+ (r[#1] Cos[#2])/
Norm[(Norm[{x'[#1], y'[#1], z'[#1]}]^2 {x''[#1], y''[#1],
z''[#1]} - {x'[#1], y'[#1], z'[#1]}.{x''[#1], y''[#1],
z''[#1]} {x'[#1], y'[#1], z'[#1]})] (Norm[{x'[#1], y'[#1],
z'[#1]}]^2 {x''[#1], y''[#1],
z''[#1]} - {x'[#1], y'[#1], z'[#1]}.{x''[#1], y''[#1],
z''[#1]} {x'[#1], y'[#1], z'[#1]})
+ (r [#1] Sin[#2] )/
Norm[{-z'[#1]*y''[#1] + z''[#1]*y'[#1],
z'[#1]*x''[#1] - z''[#1]*x'[#1], -y'[#1]*x''[#1] +
x'[#1]*y''[#1]}] {-z'[#1]*y''[#1] + z''[#1]*y'[#1],
z'[#1]*x''[#1] - z''[#1]*x'[#1], -y'[#1]*x''[#1] +
x'[#1]*y''[#1]}) &


All the arguments are functions.

Example 1:
Show[ParametricPlot3D[
Tubify[{(2 + Cos[3 #]) Cos[ #] &, (2 + Cos[3 #]) Sin[#] &,
Sin[3 #] &}, 0.25 &][u, v],
{u, 0, 2 Pi}, {v, 0, 2 Pi}, PlotStyle -> Opacity[0.2],
Mesh -> None, Boxed -> True, Axes -> False, BoxRatios -> Automatic,
PerformanceGoal -> "Quality", PlotPoints -> 80, MaxRecursion -> 0,
PlotLabel ->
Style[TraditionalForm /@ {(2 + Cos[3 t]) Cos[
t], (2 + Cos[3 t]) Sin[t], Sin[3 t]}, 20]
],
ParametricPlot3D[{(2 + Cos[3 u]) Cos[ u], (2 + Cos[3 u]) Sin[u],
Sin[3 u]}, {u, 0, 2 Pi},
PlotStyle -> Directive[{Red, Opacity[1], Thick}]], ImageSize -> 600
]


A similar code using Tube[]:

ParametricPlot3D[
{(2 + Cos[3 u]) Cos[ u], (2 + Cos[3 u]) Sin[u],
Sin[3 u]}, {u, 0, 2 Pi}, PlotStyle -> Opacity[0.2],
Mesh -> None, Boxed -> True, Axes -> False, BoxRatios -> Automatic,
PerformanceGoal -> "Quality", PlotPoints -> 80, MaxRecursion -> 0,
PlotLabel ->
Style[TraditionalForm /@ {(2 + Cos[3 t]) Cos[
t], (2 + Cos[3 t]) Sin[t], Sin[3 t]}, 20]
]/.Line[pts_, rest___] :> Tube[pts, 0.1, rest]


 Fig. 2

Example 2, trefoil knot:

Show[ParametricPlot3D[
Tubify[{Sin[#] + 2 Sin[2 #] &, Cos[#] - 2 Cos[2 #] &, -Sin[3 #] &},
0.25 &][u, v],
{u, 0, 2 Pi}, {v, 0, 2 Pi}, PlotStyle -> Opacity[0.3],
Mesh -> None, Boxed -> True, Axes -> False, BoxRatios -> Automatic,
PerformanceGoal -> "Quality", PlotPoints -> 100, MaxRecursion -> 0,
PlotLabel -> Style[TraditionalForm /@ trefoil[t], 20]
], ImageSize -> 600
]


 Fig. 3 Trefoil Knot

Similarly, we can also define the Frenet's Ribbon:
Ribbonize[{x_, y_, z_}, r_] :=
({x[#1], y[#1], z[#1]}
+ r [#1] #2 /
Norm[{-z'[#1]*y''[#1] + z''[#1]*y'[#1],
z'[#1]*x''[#1] - z''[#1]*x'[#1], -y'[#1]*x''[#1] +
x'[#1]*y''[#1]}] {-z'[#1]*y''[#1] + z''[#1]*y'[#1],
z'[#1]*x''[#1] - z''[#1]*x'[#1], -y'[#1]*x''[#1] +
x'[#1]*y''[#1]}) &


 Fig. 4, Trefoil Ribbon

 Fig. 5, Helix Ribbon

#### more examples:

 Fig. 6, A Seashell Surface
 Fig. 7, Double Helix (cf. DNA)
 Fig. 8, A Figure-eight Knot

ParametricPlot3D[
Tubify[{#/Pi Cos[#] &, #/Pi Sin[#] &, #/Pi &}, Sin[#/4] &][u, u*80],
{u, 0, 4 Pi}, PlotStyle -> Directive[{Red, Thick, Opacity[0.8]}],
Mesh -> None, Boxed -> True, Axes -> False, BoxRatios -> Automatic,
PlotRange -> All, PerformanceGoal -> "Quality", MaxRecursion -> 0,
PlotPoints -> 2560, PlotLabel -> Style["", 20],
ImageSize -> 500
]
 Fig. 9, a coilfied 3D curve