2

I have a set of particle trajectories in a 3D space and I want to represent them using 3D streamlines. I can easily get the trajectory using plot3, and I can represent the velocity vector using quiver3. As an example, one can consider the following sample script

zz = 0:pi/50:10*pi;
yy = zz.*sin(zz);
xx = zz.*cos(zz);
px=[0,diff(xx)];
py=[0,diff(yy)];
pz=[0,diff(zz)];

plot3(xx,yy,zz);
hold all;
quiver3(xx(1:5:end),yy(1:5:end),zz(1:5:end),px(1:5:end),py(1:5:end),pz(1:5:end),3);
hold off;

which produces the following plot

plot3+quiver3

I want to have the same plot, but with a 3D streamtube replacing the trajectory line. What is the most efficient way to deal with this situation?

Filburt
  • 17,626
  • 12
  • 64
  • 115
  • Check if you have the `streamtube` function (might depend on MATLAB version) – nkjt Sep 09 '14 at 10:05
  • I have it, but the problem is that the streamtube (or the streamline) function accepts as an input only a full 3D vector field (i.e. the one you can obtain from a meshgrid). – Juan Sebastian Totero Sep 09 '14 at 10:13

2 Answers2

5

You can use the option to directly insert vertices to streamtube

w = sqrt( px.^2 + py.^2 + pz.^2 );
hh = streamtube( { [xx; yy; zz]' }, {w'} );
set( hh, 'EdgeColor', 'none' );

Here's what you get

streamtube for turbulent

Shai
  • 111,146
  • 38
  • 238
  • 371
3

Usually streamtube and streamline works on vector fields, in particular in MATLAB they works only for structured meshes (i.e. those generated by meshgrid).
What you have is an unstructured vector field, but since you have a set of trajectories you actually have already the streamlines computed, indeed the trajectory are streamlines (you defined the vector field as the derivative of the trajectory).
So basically you can plot the streamlines using `plot3'.
If I understood your problem properly then a solution is the following:

clear all
close all

x = [];
y = [];
z = [];
Px = [];
Py = [];
Pz = [];

figure(1)
for i=1:10
    a= rand;
    b= rand; 
    zz{i} = 0:pi/50:10*pi;
    yy{i} = a*zz{i}.*sin(zz{i});
    xx{i} = b*zz{i}.*cos(zz{i});
    px{i}=[0,diff(xx{i})];
    py{i}=[0,diff(yy{i})];
    pz{i}=[0,diff(zz{i})];


    plot3(xx{i},yy{i},zz{i});
    hold all;

    XYZ{i} = [xx{i}',yy{i}',zz{i}'];

    x = [x, xx{i}];
    y = [y, yy{i}];
    z = [z, zz{i}];
    Px = [Px, px{i}];
    Py = [Py, py{i}];
    Pz = [Pz, pz{i}];
end
figure(2)
streamtube(XYZ)

[X,Y,Z] = meshgrid(linspace(min(x),max(x),10),linspace(min(y),max(y),10),linspace(min(z),max(z),10));
PX = griddata(x,y,z,Px,X,Y,Z);
PX(isnan(PX)) = 0;
PY = griddata(x,y,z,Py,X,Y,Z);
PY(isnan(PY)) = 0;
PZ = griddata(x,y,z,Pz,X,Y,Z);
PZ(isnan(PZ)) = 0;

figure(3)
streamtube(X,Y,Z,PX,PY,PZ,zeros(1,10),zeros(1,10),linspace(min(z),max(z),10))

this scripts generates a set of ten trajectories and then plot the streamlines with plot3 but also with streamtube. However streamtube does exactly the same job replacing the line with a tube. If you wish you can also set the width of each tube.

There is also the possibility to translate your unstructured vector field into a structured one, using the function griddata, however the result in this case will depend on how and how many the trajectory are. I would prefer the former two methods, the third could be used if you have an huge amount of trajectories and you wants to envelope all of them into a single tube.
Please let me know if this answer your question.
Alessandro

alexmogavero
  • 537
  • 2
  • 12