我在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;
产生以下情节
我想拥有相同的情节,但使用3D流管替换轨迹线。处理这种情况的最有效方法是什么?
答案 0 :(得分:4)
您可以使用该选项直接将顶点插入streamtube
w = sqrt( px.^2 + py.^2 + pz.^2 );
hh = streamtube( { [xx; yy; zz]' }, {w'} );
set( hh, 'EdgeColor', 'none' );
这是你得到的
答案 1 :(得分:3)
通常streamtube
和streamline
适用于矢量字段,特别是在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