3
$\begingroup$

This question already has an answer here:

By default, Tube has round cross-section (and we define its diameter). Is it possible to draw Tube along some known path in 3D with, e.g. square cross-section?

Thank you.

EDIT

Tried to follow answer from here. I have set of points (just an example, other arcs may have all the coordinates non-zero):

pts = {{0.`, 0.`, 0.`}, {7.497665500157259`*^-14, 0.00036555534709634656`, 0.041887873232098444`}, {2.9988378071419946`*^-13, 0.0014621100333863195`,  0.08376298663421493`}, {6.746528662189823`*^-13, 0.0032893300277940163`,  0.12561258426325045`}, {1.1991697498398906`*^-12, 0.005846658724918654`,  0.16742391794868797`}, {1.8732746539195436`*^-12, 0.009133317114586991`,  0.20918425117592362`}, {2.696762233490476`*^-12, 0.013148304019154402`,  0.25088086296604745`}, {3.669381638827055`*^-12, 0.017890396398482316`,  0.2925010517508915`}, {4.790836591859004`*^-12, 0.02335814972249914`,  0.33403213924216535`}, {6.0607854764232425`*^-12, 0.029549898411231134`,  0.37546147429349974`}, {7.478841442326563`*^-12, 0.03646375634216925`,  0.41677643675422266`}, {9.044572523187444`*^-12, 0.04409761742481735`,  0.45796444131369324`}, {1.0757501768021084`*^-11, 0.052449156242246726`,  0.499012941335023`}, {1.26171073865276`*^-11, 0.06151582875946169`,  0.5399094326770161`}, {1.4622822908039118`*^-11, 0.07129487309836018`,  0.5806414575031648`}, {1.6774037354077335`*^-11, 0.08178331037905351`, 0.6211966080765395`}, {1.9070095424469`*^-11, 0.09297794562728895`,  0.6615625305394178`}, {2.1510297696962602`*^-11, 0.10487536874769866`,  0.7017269286765003`}, {2.4093900840285483`*^-11, 0.11747195556257856`,  0.7416775676605682`}, {2.6820117840576448`*^-11, 0.13076386891588063`,  0.7814022777794407`}, {2.9688118241124915`*^-11, 0.14474705984208247`, 0.8208889581430966`}}

According to that answer first we need to have path in parametric form, to use FrenetSerretSystem. I tried to use Interpolation @ pts, but this gives me error and no result.

Then I attempted to find FindGeometricTransform between successive points in pts and apply these transformation functions to 4 points of initial rectangle (analogue of nlist in that answer). And (sub)-question here: in this my simple example initial point is (0,0,0) and inititial direction is along z-axis, so we choose some 4 points in x-y plain. And what to do in case of arbitrary initial point and direction of arc?

tf = #[[2]] & /@ (FindGeometricTransform[{#[[2]]}, {#[[1]]}] & /@ Partition[pts, 2, 1])

Then I thought I can use BSplineSurface on these computed points, but I get empty Graphics3D object.

bend = Join[ComposeList[tf, {-0.05, -0.05, 0}], ComposeList[tf, {-0.05, 0.05, 0}], ComposeList[tf, {0.05, -0.05, 0}], ComposeList[tf, {0.05, 0.05, 0}]]

Graphics3D[BSplineSurface[bend]]

So, where am I wrong? And can somebody explain in simple steps how to use that answer in my case.

EDIT2

Suppose, we have set of points with arbitrary initial one, as this:

pts1={{4.38673, -4.49861, 5.9078}, {4.36436, -4.52904, 5.93017}, {4.34115, -4.5582, 5.95338}, {4.31716, -4.58604, 5.97737}, {4.29241, -4.61254, 6.00212}, {4.26695, -4.63763, 6.02759}, {4.2408, -4.6613, 6.05373}, {4.21402, -4.6835, 6.08051}, {4.18665, -4.70419, 6.10789}, {4.15872, -4.72334, 6.13582}, {4.13028, -4.74093, 6.16426}, {4.10138, -4.75693, 6.19317}, {4.07205, -4.77131, 6.22249}, {4.04235, -4.78405, 6.2522}, {4.01232, -4.79513, 6.28224}, {3.982, -4.80454, 6.31256}, {3.95144, -4.81225, 6.34311}, {3.9207, -4.81827, 6.37386}, {3.88981, -4.82257, 6.40475}, {3.85882, -4.82515, 6.43574}, {3.82779, -4.82601, 6.46678}}

How to modify functions in answer of SquareOne?

EDIT3

Many thanks to SquareOne and J.M. for helpful comments. Now I can draw pictures like this:

enter image description here

$\endgroup$

marked as duplicate by J. M. is away Sep 29 '18 at 13:06

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 2
    $\begingroup$ See (3051), (69831) $\endgroup$ – Michael E2 Dec 12 '16 at 0:09
  • $\begingroup$ Sorry, I don't understand how to use answers you suggested. My task is very simple. I have set of points, which correspond to 3d arc. Then I can use smth like Graphics3D[Tube[BSplineCurve[points],0.7]]. Now I want this object having rectangular cross-section instead of round, as Tube has. In other words one can imagin Cuboid bended along 3d arc. $\endgroup$ – Alx Dec 12 '16 at 2:14
  • $\begingroup$ I need to draw schematically object like this inspirehep.net/record/1262850/files/3d-mag.png, but ok without internals (holes, reds etc), just solid shape. $\endgroup$ – Alx Dec 12 '16 at 2:39
  • 2
    $\begingroup$ @Alx As you posed it, the question seemed a direct duplicate. In order to prevent its closure at this point, I'd suggest that you edit your question to point out the exact reasons why the solutions presented in those two questions linked are not satisfactory to you, or what further problems you encountered while applying those solutions. $\endgroup$ – MarcoB Dec 12 '16 at 5:56
  • 3
    $\begingroup$ Graphics3D[{EdgeForm[], TubePolygons[pts, {{1, 1}, {-1, 1}, {-1, -1}, {1, -1}, {1, 1}}/30, "Normals" -> False]}, Boxed -> False], which uses routines here, yields this. $\endgroup$ – J. M. is away Dec 12 '16 at 10:21
1
$\begingroup$

So it does not appear to be doable with Tube but you can write your own if you need to. Here's some stuff to get you started:

squareTube[{p1 : {_, _, _}, p2 : {_, _, _}}, r_: .1] :=
  Module[{
    originVector = p2 - p1,
    zAxis = {0, 0, 1},
    zCross, zAngle, zVector,
    xAxis = {1, 0, 0},
    xCross, xAngle, xVector,
    graphic},
   zAngle = VectorAngle[originVector, zAxis];
   If[! (zAngle == 0 || zAngle == \[Pi]),
    zCross = originVector~Cross~zAxis;
    zVector = RotationMatrix[zAngle, zCross].originVector,
    zCross = {0, 0, 0};
    zVector = originVector
    ];
   xAngle = VectorAngle[zVector, xAxis];
   If[! (xAngle == 0 || xAngle == \[Pi]),
    xCross = zVector~Cross~xAxis;
    xVector = RotationMatrix[xAngle, xCross].zVector,
    xCross = {0, 0, 0};
    xVector = zVector
    ];
   With[{starts = 
      Join @@ Table[{-r, y, z}, {y, {r, -r}}, {z, {r, -r}}]},
    With[{ends = Table[{2 r, 0, 0} + xVector + v, {v, starts}]},
     graphic = {Prism@Join[Most@starts, Most@ends], 
       Prism@Join[Rest@starts, Rest@ends]}
     ]
    ];
   If[xCross != {0, 0, 0},
    graphic = Rotate[graphic, -xAngle, xCross]
    ];
   If[zCross != {0, 0, 0},
    graphic = Rotate[graphic, -zAngle, zCross]
    ];
   {EdgeForm[None],Translate[graphic, p1]}
   ];
squareTube[Line[p : {__}], r_: .1] :=

  squareTube[#, r] & /@ MapThread[List, {Most@p, Rest@p}];

This simply pulls and rotates each line segment so that it lies along the x-axis starting at the origin, creates a rectangular tube from the origin to the end of the segment (extended by the radius of the tube), and then rotates and translates this back into place.

Here's an example:

With[{p = {
    {0, 0, 0},
    {0, 0, 1},
    {0, 1, 1},
    {0, 1, 0},
    {0, 0, 0}
    }
  },
 squareTube[Line@p, .1]
  // Graphics3D
 ]

example

Note that figuring out how to do the joins will be pretty nasty:

With[{p = Partition[RandomReal[10, 3*5], 3]},
 squareTube[Line@p, .1]
  // Graphics3D
 ]

example 2

$\endgroup$
0
$\begingroup$
Show[Graphics3D[
   Line[{{0, 0, 0}, {3, 0, 0}, {3, 0, 3}, {0, 0, 3}, {0, 0, 0}}]] /. 
  Line -> (Tube[#, 0.2] &), PlotRange -> All, Labeled -> False, 
 Axes -> False]

enter image description here

$\endgroup$
  • $\begingroup$ Thank you for the clarification. I am looking but do not think there is a Head function to allow a square configuration. $\endgroup$ – Jose Enrique Calderon Dec 12 '16 at 2:34
  • 2
    $\begingroup$ Jose, I think the OP meant that the cross-section of the Tube-like object should be a square, whereas in your example the cross section is still a disk. $\endgroup$ – MarcoB Dec 12 '16 at 4:10

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