从粒子轨迹数据创建3D流管(或流线)

时间:2014-09-09 09:07:57

标签: matlab 3d matlab-figure particles

我在3D空间中有一组粒子轨迹,我想用3D流线表示它们。我可以使用plot3轻松获得轨迹,我可以使用quiver3表示速度矢量。例如,可以考虑以下示例脚本

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;

产生以下情节

plot3+quiver3

我想拥有相同的情节,但使用3D流管替换轨迹线。处理这种情况的最有效方法是什么?

2 个答案:

答案 0 :(得分:4)

您可以使用该选项直接将顶点插入streamtube

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

这是你得到的

streamtube for turbulent

答案 1 :(得分:3)

通常streamtubestreamline适用于矢量字段,特别是在MATLAB中,它们仅适用于结构化网格(即meshgrid生成的网格)。 你所拥有的是一个非结构化的矢量场,但由于你有一组轨迹,你实际上已经计算了流线,实际上轨迹是流线(你将矢量场定义为轨迹的导数)。
所以基本上你可以使用`plot3'来绘制流线图 如果我理解你的问题,那么解决方案如下:

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))

此脚本生成一组十个轨迹,然后使用plot3绘制流线图,同时使用streamtube绘制流线图。但是streamtube完成了用管替换线的完全相同的工作。如果您愿意,还可以设置每个管的宽度。

还可以使用函数griddata将非结构化矢量场转换为结构化矢量场,但是在这种情况下,结果将取决于轨迹的方式和数量。我更喜欢前两种方法,如果你有大量的轨迹并且你想将它们全部包装在一根管中,那么第三种方法就可以使用了。
如果这回答了你的问题,请告诉我 的Alessandro