Search code examples
matlabmupad

Generate tubes with non-circular cross-sections in MuPad


Using plot::tube function in MuPAD, I can generate tubes with varying spine but the cross-section is always a circle, although the radius can vary along the spine. For instance:

plot::Tube([cos(t), sin(t), 0], 0.4 + 0.3*sin(t)*cos(t),t = -0.5*PI..0.5*PI,Mesh=[60,12]):

I want to plot tubes with (non-circular) elliptical cross-sections. Is there a way to achieve this in MuPAD?

P.S. I can generate tubes with arbitrary cross-sections using MATLAV, so please avoid including answers that use pure MATLAB commands.


Solution

  • As for your first question whether this can be done with plot::Tube: I don't think so. Consider the help of this function (emphasis mine):

    plot::Tube creates generalized tubular plots, known as "canal surfaces", with special cases known as "tube surface", "pipe surface" or "tubular surfaces."

    Intuitively, canal surfaces are space curves with thickness. More formally, a canal surface plot::Tube([x(t), y(t), z(t)], r(t), t = t_min..t_max) is the envelope of spheres with center [x(t), y(t), z(t)] and radius r(t), i.e., the thickness of the curve can vary with the curve parameter t

    The fact that a tube is defined as an envelope of a collection of spheres suggests that their cross-section is inherently circular.

    I'm not familiar with MuPAD, so I don't know the elegant solution to your problem. For your simple example of a semi-circular base line I could put together this kludgy solution using the low-level plot::Surface, manually constructing the surface:

    plot(
      plot::Surface(
          matrix([cos(t),sin(t),0]) 
          + numeric::rotationMatrix(t,[0,0,1]) * matrix([(0.2+0.1*sin(2*t))*cos(u),0,(0.2+0.1*cos(2*t))*sin(u)]),
          t = -PI/2..PI/2,
          u = 0..2*PI,
          Mesh = [30,30]),
      Scaling=Constrained)
    

    output

    Here t stands for the angular parameter along the semi-circular base line (toroidal direction), and u is the angle along the cross-section (poloidal direction). A given cross-section at angle t looks like this:

    [(0.2+0.1*sin(2*t))*cos(u), 0, (0.2+0.1*cos(2*t))*sin(u)]
    

    I.e. the semimajor axes are (0.2+0.1*sin(2*t)) and (0.2+0.1*cos(2*t)) along the cross-section of the tube.

    You can see that I used a rotation matrix around the z axis to construct the surface. This made heavy use of the fact that the base line is a semi-circle. However, in general cases it should be possible to compute the derivative of your parameterized base line (with respect to t), and compute the necessary rotation angle (with parameter t) from that.