Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Say I have a 3D curve that is parametrically defined. How would I be able to plot shapes like figure 8s whose centers are aligned along the 3D curve?

Say the curve was:

P[a_]:={-a,a,1/2 a (8-a)};

Does anyone know how I might be able to do this?

share|improve this question

1 Answer 1

up vote 9 down vote accepted

For this, you could use the answer by J.M. to the question "Extruding along a path". The question here isn't a duplicate because it makes use of features in J.M.'s excellent answer that go beyond what the linked question actually asked for. In particular, that answer can deal with self-intersecting cross sectional curves, which is what you need for this question:

So what you have to do is: first copy the definitions in J.M.'s answer and then define your custom cross section:

cs = First@
     BSplineFunction[{{0., 0.}, {0.25, 0.25}, {0.25, 0.}, {0., 0.25}},
         SplineClosed -> True][u] // Evaluate, {u, 0, 1}, 
     MaxRecursion -> 1], Line[l_] :> l, Infinity];

Graphics3D[{EdgeForm[], TubePolygons[path, cs]}, Boxed -> False]


For your arch example, it looks like this:

P[a_] := {-a, a, 1/2 a (8 - a)};
path = First@
   Cases[ParametricPlot3D[P[a], {a, 0, 8}, MaxRecursion -> 1], 
    Line[l_] :> l, Infinity];

Graphics3D[{EdgeForm[], TubePolygons[path, 5 cs]}, Boxed -> False]


Edit: discrete shapes

Here is a discrete version where the shapes are inserted at positions given in a table. For the math behind the rotation transformation, have a look at "Finding unit tangent, normal, and binormal vectors for a given r(t)":

figureEight = 
  BSplineFunction[{-{0.25, 0.25}, {0.25, 0.25}, {0.25, -.25}, {-.25, 
       0.25}}, SplineClosed -> True][u] // Evaluate, {u, 0, 1}, 
  MaxRecursion -> 1]


cs = First@Cases[figureEight, Line[l_] :> l, Infinity];


r[t_] := P[t]

uT[t_] = Simplify[r'[t]/Norm[r'[t]], t \[Element] Reals];

vN[t_] = Simplify[uT'[t]/Norm[uT'[t]], t \[Element] Reals];

vB[t_] = Simplify[Cross[uT[t], vN[t]], t \[Element] Reals];

  {P[t]}, {t, 0, 8}, PlotStyle -> {Blue, Thick}],
     GeometricTransformation[Tube@Line[Map[Append[#, 0] &, 10 cs]], 
      Transpose[{vN[s], vB[s], uT[s]}]], P[s]]}], {s, 0, 8}], 
 PlotRange -> 10 {{-1.1, .2}, {-.2, 1.1}, {-.2, 1.1}}]


The matrix in GeometricTransformation is made up of the three unit vectors tangent, normal, and bi-normal to the arc curve. The figure-eight shape is centered at the origin in a 2D coordinate system, so we have to first use Append to add a z-coordinate 0 to its points, and then align the orthogonal Cartesian axes with the normal and bi-normal vectors at a given point along the curve. Finally, the whole shape is translated to the location P[s] where s is the curve parameter.

share|improve this answer
Of course I may be misunderstanding the question. Maybe the "shapes" are supposed to be discrete. But in the absence of a specific statement, I assumed the shapes are as continuous as the path itself. –  Jens Jul 29 '13 at 17:45
Yes I meant that the shapes would be discrete and that maybe i could specify the interval on which they appear. By my intuition I figured I should find an equation for the planes perpendicular to the curve at all points and then write a formula for the shape on those planes. I just dont know how to go about doing this. –  J. Musk Jul 29 '13 at 17:51
I updated the answer with a discrete version of the shape. –  Jens Jul 29 '13 at 18:47

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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