Tuba Package Examples

0. Setup

First open and save tuba.nb to generate tuba.m. Then load package as in

<<"mydirectory/Tuba.m"

I. Simple Tubes and Ribbons

The basic command tube[curve, color, radius]  draws a tube around a curve. The curve can be given either as a function f:[0,1] -> (ℝ^3) or as a list of  {x,y,z} coordinates.If the curve is given by a function, the function must already be named and defined in a previous line. The second variable gives intrinsic surface colour. Tuba automatically loads the Graphics`Colors package which gives names to a variety of colours. The command AllColors lists the colours.

\(circlefun[t_]\  := \ 4 {Cos[2\ Pi\ t], \ Sin[2\ Pi\ t], \ 0}; 

    tube[circlefun, \ Turquoise, \ 1]\  // \ Show; \)

The function todata changes circlefun to a list,just for fun done here with only 4 evaluation points. Tube defaults to 40 plotting points along the axis,which it finds from the evaluation points using cubic interpolation. A list of points can be fed to tube as well as a function.The command quicktube[curve] chooses unit radius and a white surface color,and sends the result to Show.

circlelist  =  todata[circlefun, 4]quicktube[circlelist];

We can put some twist on the tube.For example, tubehelicity -> 2 adds two full twists around the axis. We first set a few Graphics3D Options.

\(SetOptions[Graphics3D, \ Background -> \ GrayLevel[0.5], \ 
      Boxed\  -> \ False]; 

    tube[circlefun, \ Gold, \ 1, \ tubehelicity\  -> \ 2] // Show; \)

Tubes have nalongtube plotpoints along the axis, and naroundtube plotpoints around. We can create a ribbon by setting naroundtube to 2:

\(ribboncolors\  = \ {EdgeForm[Blue], \ Eggshell}; 

    mobiusstrip\  = \ 
      tube[circlefun, \ ribboncolors, 0.6, \ tubehelicity\  -> \ \(-0.5\), \ 
          naroundtube -> \ 2] // Show; \)

II. Normals, Binormals, Twist, and Range

There are three algorithms for finding the circles normal to the curve axis. The default is Frenet normal and binormal. Others are
tubealgorithm -> xytube (circles in xy plane), and tubealgorithm -> {a,b,c} (normal = tangent x {a,b,c} ).

helix[t_]  :=  {3 Sin[4 Pi t],  3 Cos[4 Pi t],  20 t};

\(frenet\  = \ tube[helix, \ Eggshell, \ 1]\ ; 

    fixed\  = \ 
      tube[helix, \ \ Eggshell, 1, \ tubealgorithm\  -> {1, 0, 0}]\ ; 

    xy\  = \ tube[helix, \ \ Eggshell, 1, tubealgorithm\  -> \ xytube]\ ; 

    GraphicsArray[{frenet, \ fixed, \ xy}] // Show; \)

The function tuberange allows you to cut away unwanted polygons where tuberange <0:

\(rangefun[{x_, \ y_, \ z_}]\  := \ Abs[z\  - \ 10]\  - \ 3; 

    sue\  = \ tube[helix, \ EmeraldGreen, \ 1, \ 
          tuberange\  -> \ rangefun] // Show; \)

III. Colourful Tubes

We can use any graphics directive we like in the second slot of tube.  We will use two directives, EdgeForm[Red] and surface colour Gold. For more than one directive, they must be put inside curly brackets{}. By default, the reflectivity of the surface is increased to 15, to improve the 3D picture quality.

\(circlefun[t_]\  := \ 4 {Cos[2\ Pi\ t], \ Sin[2\ Pi\ t], \ 0}; 

    tube[circlefun, \ {EdgeForm[Red], Gold}, \ 1] // Show; \)

We can add lines separately going along the axis (say 3), or around the axis (say 8) using the fluxline function:

borderlines  =  
      fluxlines[circlefun,  1.1, 3,  8,  fluxcolor  ->  Blue,  
        fluxthickness  ->  0.01]

Here is the first set of lines:

Show[borderlines[[1]]];

Here is the second set of lines, along with the surface, drawn with no lines of its own (EdgeForm[]). Hint: a few commands ago borderlines was called with radius set at 1.1 -- this was to make sure the lines are completely outside of the radius 1 tube.

Show[tube[circlefun,  {EdgeForm[], Gold},  1],  
      borderlines[[2]]];

Now specify colour as a function of position. Here s ranges from 0 to 1 and gives position around the tube, while t goes along the tube from 0 to 1. First we make the surface smoother by making more plot points (this will slow things down, of course):

\(SetOptions[tube, \ naroundtube\  -> \ 20, nalongtube -> 40]; 

    SetOptions[Graphics3D, \ Boxed -> False]; \)

\(rainbow[s_, t_] := {EdgeForm[], SurfaceColor[Hue[s]]}; 

    tube[circlefun, \ rainbow, \ 1, \ tubehelicity -> \(-2\)] // Show; \)

IV. Shapely Tubes

The third variable in tube can be radius from the axis as a function of position [s,t], where s goes around the tube from 0 to 1, and t goes along the axis from 0 to 1.

shell[s_, t_] :=  .1  + 3  t  +   2  t^8;

\(circlefun[t_]\  := \ 4 {Cos[2\ Pi\ t], \ Sin[2\ Pi\ t], \ 0}; 

    partcirc[t_] := \ circlefun[0.7  t\  + \ 1]; \)

tube[partcirc,  {EdgeForm[],  Gold},  shell] // Show;

V. Whitehead Link with Arrows

The function sidearrow places an arrow on a tube plot. It knows about the viewing angle so the arrow never gets hidden behind the tube.

More details: sidearrow[fun, t, eps, radius, theta] draws a red arrow with tail at fun[t] and tip at  fun[t+eps]. The arrow is displaced by radius in the default viewing direction (ViewPoint). Use, e.g.  SetOptions[Graphics3D, ViewPoint -> {-1,1,3}] to change ViewPoint so that sidearrow knows about it. It can be rotated away from the viewing direction by the angle theta.

\(figure8[t_]\  = 
      \ {3\ Cos[2\ Pi\ t], 3\ Sin[4\ Pi\ t], \ Sin[2\ Pi\ t]}; 
\ 
    circe[t_]\  = \ 2 {\ Cos[2\ Pi\ t], \ 0, \ Sin[2\ Pi\ t]}; \)

SetOptions[Graphics3D,  ViewPoint -> {0.886,  -2.777,  1.718}, 
       Boxed  ->  False,  RenderAll  ->  True];

\(\(whitehead\  = \ 
      Show[
			
        tube[figure8, \ {EdgeForm[], Yellow}, \ 0.4, \ 
          tubealgorithm\  -> {0, 0, 1}], 
			
        tube[circe, \ {EdgeForm[], Turquoise}, \ 0.4], 
        sidearrow[figure8, \ 0. , \ 0.06, \ 0.6, \ 0, \ arrowcolor -> Blue], 
        \ sidearrow[circe, \ 0. , \ 0.13, \ 0.6, \ 0]
		\ ]; \)\)

VI. Braids

\(SetOptions[Graphics3D, \ \ Background\  -> \ GrayLevel[0], \ 
      ViewPoint\  -> \ {0, \(-3\), 1}, \ PlotRange -> \ All, \ 
      Boxed -> False]; 

    SetOptions[tube, \ naroundtube\  -> \ 20, nalongtube -> 80, \ 
      tubealgorithm -> {1, 1, 0}]; \)

\(size\  = 5; height\  = 50; 

    pigfunction[z_]\  := \ {Sin[2\ Pi\ z], \ Sin[4\ Pi\ z]}\)\(curve1[z_]\  := \ Join[\ size\ pigfunction[z], \ height\ {z}]; 

    curve2[z_]\  := \ Join[\ size\ pigfunction[z\  - \ 1/3], \ height\ {z}]; 
    
curve3[z_]\  := \ 
      Join[\ size\ pigfunction[z\  + \ 1/3], \ height\ {z}]; 

    pigtail\  = \ {curve1, curve2, \ curve3}; \)

The function tress[braid] creates a graphics3D object including tubes around each curve in the braid, as well as an upper and lower boundary. Go get some coffee -- this can be slow!

pig  =  tress[pigtail, 2] // Show;

VII. Torusknots, Arches, and Artin Braids

Torus knots: torusknot[p,q, majorradius,minorradius, t] is a function of t which gives a torusknot curve. The curve is periodic in t with period 1. It is imbedded in a torus described by majorradius and minorradius, and goes p times the long way around and q times the short way around.

\(SetOptions[Graphics3D, \ \ Background\  -> \ GrayLevel[0.5], \ 
      ViewPoint -> {\(-1. \), \ \(-3. \), \ 1}, \ PlotRange -> \ All, \ 
      Boxed -> False]; 

    SetOptions[tube, \ naroundtube\  -> \ 12, nalongtube -> 100, \ 
      tubehelicity -> \ 1, \ tubealgorithm -> frenet]; \)

\(knot53[t_] := \ torusknot[5, 3, 20, 8, t]; 

    tube[knot53, \ {EdgeForm[], \ Eggshell}, \ 1] // Show; \)

Arches: arch[{x1, y1}, {x2, y2}, t] gives a halfcircle in a verticle plane from {x1, y1,0} to {x2, y2, 0}. For more complicated loops above z=0, consider drawing a full circle or ellipse, then cutting off the part below z=0 by creating a function range[z_] = z, then setting tuberange -> range for the tube graphics routine.

\(corner\  = \ 3; 

    laurel[t_] := \ arch[corner {\(-1\), \ \(-1\)}, \ corner {1, 1}, \ t]; \ 
    
hardy[t_] := \ 
      arch[2  corner {\(-1\), \ 1}, \ 1.5\ corner {1, \(-1\)}, \ t]; 

    xyplane\  = \ 
      Graphics3D[
        Polygon[3  
            corner {\ {1, 1, \ 0}, \ {1, \ \(-1\), \ 0}, 
              \ {\(-1\), \(-1\), \ 0}, \ {\(-1\), \ 1, \ 0}}]]; \)

{xyplane,  tube[laurel,  {EdgeForm[],  Banana},  1],  
        tube[hardy,  {EdgeForm[],  MistyRose},  1]} // Show;

Artin Braids: Let's draw a braid with 6 strings, only four of them braided, with radii 1, distance between endpoints 5, and distance between top and bottom 50. First an Artin word which only braids four strings:

tangledstrings  =  {1, -2, 3, -2, 1, 3, -2, 3, 1};

Next feed this to artin[word, nstrings]. This creates a set of curves which is rescaled by scaledbraid to have distance between endpoints 5 and distance between top and bottom 50. scaledbraid[braid, xyscale, n] first converts braid to a set of lists of length n.   It then chooses z values so that the ith point in the list for each curve is at z=i-1. Finally feed to tress to see what it looks like!

thisbraid  =  scaledbraid[artin[tangledstrings,  6],  5,  50];

\(SetOptions[Graphics3D, \ \ Background\  -> \ GrayLevel[0.5], \ 
      ViewPoint -> {\(-1. \), \ \(-3. \), \ 1}, \ PlotRange -> \ All, \ 
      Boxed -> False]; 

    SetOptions[tube, \ naroundtube\  -> \ 8, nalongtube -> 100, \ 
      tubehelicity -> \ 0, \ tubealgorithm -> {1, 1, 0}]; \)

tress[thisbraid,  1] // Show;