Extruding along a path

In Mathematica 7 or 8, you can just use Tube. Please see the docs for many, many examples.

Example:

Show[ParametricPlot3D[{Cos[x], Sin[x], x/5}, {x, 0, 15}] /. 
  Line -> (Tube[#, 0.2] &), PlotRange -> All]

Mathematica graphics


This question has been nicely addressed by the previous answers, so I'll just write about a method you can use if you want your tube to have custom cross-sections; or, like in this question, you need to have the tube as a bunch of Polygon[]s.

(* Pixar method; http://jcgt.org/published/0006/01/01/ *)
orthogonalDirections[{p1_?VectorQ, p2_?VectorQ}] := Module[{s, w, w1, xx, yy, zz},
     {xx, yy, zz} = Normalize[p2 - p1];
     s = 2 UnitStep[zz] - 1; w = -1/(s + zz); w1 = xx yy w;
     {{1 + s w xx^2, s w1, -s xx}, {w1, s + w yy^2, -yy}}]

orthogonalDirections[{p1_?VectorQ, p2_?VectorQ, p3_?VectorQ}] := Module[{d, u, v},
     {u, v} = Normalize /@ {p3 - p2, p1 - p2};
     If[Chop[Norm[u - v] Norm[u + v]] != 0,
        d = (u + v)/2; Normalize /@ {d, Cross[u, d]},
        orthogonalDirections[{p1, p2}]]]

extend[cs_, q_, d_, nrms_] :=
cs + Outer[Times, First[LinearSolve[Transpose[Prepend[-nrms, d]],
                                    q - Transpose[cs]]], d]

(* for custom cross-sections *)
crossSection[pointList_?MatrixQ, r_, csList_?MatrixQ] := Module[{p1, p2},
     {p1, p2} = Take[pointList, 2];
     (p1 + #) & /@ (r csList.orthogonalDirections[{p1, p2}])] /; 
Last[Dimensions[pointList]] == 3 && Last[Dimensions[csList]] == 2

(* for circular cross-sections *)
crossSection[pointList_?MatrixQ, r_, n_Integer] := 
 crossSection[pointList, r, Composition[Through, {Cos, Sin}] /@ Range[0, 2 Pi, 2 Pi/n]]

(* approximate vertex normals, for a smooth appearance *)
vertNormals[vl_ /; ArrayQ[vl, 3, NumericQ]] := Block[{mdu, mdv, msh},
    msh = ArrayPad[#, {{1, 1}, {1, 1}}, "Extrapolated", InterpolationOrder -> 2] & /@
          Transpose[vl, {2, 3, 1}];
    mdu = ListCorrelate[{{1, 0, -1}}/2, #, {{-2, 1}, {2, -1}}, 0] & /@ msh;
    mdv = ListCorrelate[{{-1}, {0}, {1}}/2, #, {{1, -2}, {-1, 2}}, 0] & /@ msh;
    MapThread[Composition[Normalize, Cross], Transpose[{mdu, mdv}, {1, 4, 2, 3}], 2]]

MakePolygons[vl_ /; ArrayQ[vl, 3, NumericQ], OptionsPattern[{"Normals" -> True}]] :=
Module[{dims = Most[Dimensions[vl]]}, 
       GraphicsComplex[Apply[Join, vl], 
                       Polygon[Flatten[Apply[Join[Reverse[#1], #2] &, 
                       Partition[Partition[Range[Times @@ dims], Last[dims]],
                                 {2, 2}, {1, 1}], {2}], 1]], 
                       If[TrueQ[OptionValue["Normals"] /. Automatic -> True], 
                          VertexNormals -> Apply[Join, vertNormals[vl]], 
                          Unevaluated[]]]]

Options[TubePolygons] = {"Normals" -> True, "Scale" -> 1.};
TubePolygons[path_?MatrixQ, cs : (_Integer | _?MatrixQ), OptionsPattern[]] :=
With[{p3 = PadRight[path, {Automatic, 3}]},
     MakePolygons[FoldList[Function[{p, t}, 
                                    extend[p, t[[2]], t[[2]] - t[[1]],
                                           orthogonalDirections[t]]], 
                           crossSection[p3, OptionValue["Scale"], cs], 
                           Partition[p3, 3, 1, {1, 2}, {}]], 
                  "Normals" -> OptionValue["Normals"]]]

Try it out:

path = First @ Cases[ParametricPlot3D[BSplineFunction[
       {{0, 0, 0}, {1, 1, 1}, {2, -1, -1}, {3, 0, 1}, {4, 1, -1}}][u] // Evaluate,
     {u, 0, 1}, MaxRecursion -> 1], Line[l_] :> l, Infinity];

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

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

B-spline tube with B-spline cross section

Of course, you can elect to have a circular cross section, as is usual:

Graphics3D[{EdgeForm[], TubePolygons[path, 20, "Scale" -> .2]}, Boxed -> False]

B-spline tube with circular cross section


I see you mentioned splines in your question. Your picture is 3D, but you used 2D {x,y} coordinates in the question. This little example uses a random set of control points and emphasizes the 3D nature of the Tube and {x,y,z} coordinates:

points = RandomReal[1, {20, 3}]; 
Export["tube.gif",
   Table[
      Graphics3D[
         {Orange, Specularity[White, 100], Tube[BSplineCurve[points], .03]},
         Boxed -> False, SphericalRegion -> True,
         ViewAngle -> .25, 
         ViewPoint -> RotationTransform[a, {0, 0, 1}][{3, 0, 3}]], 
      {a, 0, 2 Pi, .1}
   ]]

tube through random points