I need a tube with only one end capped. I can do this relatively easily with:

monoTube[{pt1_, pt2_}, r_] := {
  Cylinder[{pt1, pt2}, r],
  Sphere[pt2, r]}

I would also like the entire object to have the length EuclideanDistance[pt1, pt2], which means I really need a pt3 lying on the object's path that is closer to pt1 than pt2 is by the distance r. While I know this is a simple vector operation, I do not know how to do it properly.

monoTube [{pt1_, pt2_}, r_] := {EdgeForm[None], Cylinder[{pt1, pt2}, r], Sphere[pt2, r]}
monoTube1[{pt1_, pt2_}, r_] :=   
                          With[{s = (Norm[pt2 - pt1] - r) Normalize[pt2 - pt1] +  pt1}, 
                              {EdgeForm[None], Cylinder[{pt1, s}, r], Sphere[s, r]}]

Graphics3D[{monoTube [{{0, 0, -1}, {0, 0, 1}}, 1], 
            monoTube1[{{2, 0, -1}, {2, 0, 1}}, 1]}, Axes -> True]

Mathematica graphics

  • $\begingroup$ That's what I'm looking for; clearly, I need to crack open a linear algebra book. $\endgroup$ – bobthechemist Aug 21 '15 at 23:29

Use two Tube[]s:

monoTube[{p1_?VectorQ, p2_?VectorQ}, r_?NumericQ] := 
        Module[{h = 1 + $MachineEpsilon^(3/4), pm, t},
               t = r/EuclideanDistance[p1, p2];
               pm = t p1 + (1 - t) p2;
               {{CapForm[None], Tube[{p1, pm}, r]}, 
                Tube[{t h p1 + (1 - t h) p2, pm}, {0, r}]}]

Graphics3D[monoTube[{{0, 0, 0}, {-1, 1, 1}}, 0.1]]

tube with a single cap

  • $\begingroup$ Neat idea. I did not know one could obtain pm the way you have. Do you know why h is needed? $\endgroup$ – bobthechemist Aug 21 '15 at 23:27
  • $\begingroup$ @bob, prolly should've linked to this to begin with. :) $\endgroup$ – J. M.'s ennui Aug 22 '15 at 0:18

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.