3
$\begingroup$

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

monoTube[{pt1_, pt2_}, r_] := {
  EdgeForm[None],
  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.

$\endgroup$
0

2 Answers 2

3
$\begingroup$
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

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

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

$\endgroup$
2
  • $\begingroup$ Neat idea. I did not know one could obtain pm the way you have. Do you know why h is needed? $\endgroup$ Aug 21, 2015 at 23:27
  • $\begingroup$ @bob, prolly should've linked to this to begin with. :) $\endgroup$ Aug 22, 2015 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.