5
$\begingroup$

Is it possible to easily make "dashed" tubes? In two dimensions I can easily dash lines,

ListPlot[{{0, 0}, {1, 1}}, Joined -> True, PlotStyle -> Dashed]

dashed line

I'd like the same effect, but in three dimensions. Start with a tube (potentially not just given by points, but by a BSplineCurve or BezierCurve,

Graphics3D[{
   Tube[{{0, 0, 0}, {1, 1, 1}}],
   Tube[BezierCurve[{{0, 0, 0}, {1/2, 1/2, 1}, {1, 1, 1}}]],
   Tube[BSplineCurve[{{0, 0, 0}, {1, 1, 1/2}, {1, 1, 1}}]]
   }]

solid tubes

Is it possible to use some styling or graphics directive to cause the tubes to be broken up into smooth, regularly-shaped, little pieces? Inserting Dashed, eg. Graphics3D[{Dashed, ..., doesn't work.

If not, what is a good solution for achieving such an effect? Supporting Dotted, DotDashed, Dashing and Tube's CapForm for the segments would be great.

$\endgroup$
10
$\begingroup$

You can define functions:

bsf1 = BezierFunction[{{0, 0, 0}, {1/2, 1/2, 1}, {1, 1, 1}}];
bsf2 = BezierFunction[{{0, 0, 0}, {1, 1, 1/2}, {1, 1, 1}}];

then trace them with gaps with small Tube or Cylinder:

ln1 = Tube[#, .01] & /@ Partition[Table[bsf1[n], {n, 0, 1, .01}], 2][[1 ;; -1 ;; 2]];
ln2 = Tube[#, .01] & /@ Partition[Table[bsf2[n], {n, 0, 1, .03}], 2][[1 ;; -1 ;; 1]];

Graphics3D[{Tube[{{0, 0, 0}, {1, 1, 1}}], ln1, ln2}]

enter image description here

$\endgroup$
5
$\begingroup$

Vitaliy's answer can easily be adapted into exactly what I'm looking for. Here's the code I wound up with in the end:

(* The user can just pass a list:*)
dashedTube[on_, off_, OptionsPattern[Tube]][func_List, radius_: 0.01, each___] := 
    dashedTube[on, off][BSplineFunction[func, SplineDegree -> 1], radius, each]

(* or a BSpline/BezierFunction: *)
dashedTube[on_, off_, OptionsPattern[Tube]][func_, radius_: 0.01,  each___] := 
    Tube[#[[All, 2]], radius, each,
        If[OptionValue[VertexColors] === Automatic, 
           VertexColors -> Automatic, 
           VertexColors -> (Blend[OptionValue[VertexColors], #] & /@ #[[All,1]])]
    ] & /@ Partition[{#, func[#]} & /@ Union@Clip[
  FoldList[Plus, 0, {on, off}[[1 + 
      Mod[Range[0, Ceiling[2/(on + off)]], 2]]]], {0, 1}], 2]

Now, using bsf1 and bsf2 from Vitaliy's answer,

Graphics3D[{
    CapForm["Round"],
    dashedTube[0.05, 0.03, VertexColors -> {Red, Green}][ bsf1, 0.02],
    dashedTube[0.1, 0.02][{{0, 0, 0}, {1, 1, 1}}, 0.015, VertexColors -> {Blue, Purple}],
    CapForm["Square"],
    dashedTube[0.03, 0.03][bsf2, 0.02, VertexColors -> {Red, Green}]
}]

The each optional variable applies style to each individual dash, while the options in the curried head apply to the whole string.

dashing tubes

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.