Построение эволюции 2D вектора в 3D как ленты в MATLAB - PullRequest
3 голосов
/ 20 октября 2010

Я хотел бы показать, как амплитуда и ориентация двумерного вектора эволюционируют со временем.Для этого я хотел бы создать график, напоминающий канонические графы полей E & B, которые вы можете вспомнить из вводного класса электричества и магнетизма.

В частности, я хотел бы соединить свои двухмерные векторные точки с лентой, чтобы их было легко увидеть.Есть ли простой способ сделать это в MATLAB?quiver3 довольно близко, но ему не хватает ленты.Возможно, какая-то параметрическая поверхность?

Ответы [ 2 ]

5 голосов
/ 20 октября 2010

Вы можете использовать функции построения FILL3 и QUIVER3 , чтобы сделать что-то вроде этого:

x = linspace(0,4*pi,30);  %# Create some x data
y1 = sin(x);              %# Create wave 1
y2 = sin(x-pi);           %# Create wave 2
u = zeros(size(x));       %# Create a vector of zeroes

hRibbon1 = fill3(x,y1,u,'r');     %# Plot wave 1 and fill underneath with color
set(hRibbon1,'EdgeColor','r',...  %# Change the edge color and
             'FaceAlpha',0.5);    %#   make the colored patch transparent
hold on;                          %# Add to the existing plot
quiver3(x,u,u,u,y1,u,0,'r');      %# Plot the arrows

hRibbon2 = fill3(x,u,y2,'b');     %# Plot wave 2 and fill underneath with color
set(hRibbon2,'EdgeColor','b',...  %# Change the edge color and
             'FaceAlpha',0.5);    %#   make the colored patch transparent
quiver3(x,u,u,u,u,y2,0,'b');      %# Plot the arrows
axis equal;                       %# Use equal axis scaling

И вот результирующий график:

alt text

3 голосов
/ 21 октября 2010

вот решение, которое рисует ленту между любыми двумя линиями в трехмерном пространстве.Вы можете нанести на него свой колчан и настроить непрозрачность, используя «FaceAlpha», как в решении gnovice

Чтобы сделать функцию более понятной, я сначала публикую ее без функций проверки ошибок и изменения размера (которые составляют большую частьтело функции и не особенно интересно)

function h = filledRibbon (x,y,z,u,v,w,c, varargin)
%function filledRibbon (x,y,z,u,v,w,c, varargin)
%
%plots a ribbon spanning the area between the lines x,y,z and x+u,y+v,z+w
%in the color c
%varargin is passed directly to patch
%returns a handle to the patch graphic created

%make up a set of regions that span the space between the lines

xr = [x(1:end-1); x(1:end-1) + u(1:end-1); x(2:end) + u(2:end); x(2:end)];
yr = [y(1:end-1); y(1:end-1) + v(1:end-1); y(2:end) + v(2:end); y(2:end)];
zr = [z(1:end-1); z(1:end-1) + w(1:end-1); z(2:end) + w(2:end); z(2:end)];

%plot the regions with no edges
h = patch(xr,yr,zr,c, 'LineStyle','none', varargin{:});

используйте эту версию для проверки ошибок в вашем фактическом коде:

function h = filledRibbon (x,y,z,u,v,w,c, varargin)
%function filledRibbon (x,y,z,u,v,w,c, varargin)
%
%plots a ribbon spanning the area between the lines x,y,z and x+u,y+v,z+w
%in the color c
%varargin is passed directly to patch
%returns a handle to the patch graphic created


if ~exist('w', 'var') || isempty(w)
    w = 0;
end
if ~exist('u', 'var') || isempty(u)
    u = 0;
end
if ~exist('v', 'var') || isempty(v)
    v = 0;
end
if ~exist('c', 'var') || isempty(c)
    c = 'b';
end


%make all vectors 1xN 
x = reshape(x,1,[]);
y = reshape(y,1,[]);
z = reshape(z,1,[]);

%if any offsets are scalar, expand to a vector
if all(size(u) == 1)
    u = repmat(u, size(x));
end

if all(size(v) == 1)
    v = repmat(v, size(x));
end
if all(size(w) == 1)
    w = repmat(w, size(x));
end

%make up a set of regions that span the space between the lines

xr = [x(1:end-1); x(1:end-1) + u(1:end-1); x(2:end) + u(2:end); x(2:end)];
yr = [y(1:end-1); y(1:end-1) + v(1:end-1); y(2:end) + v(2:end); y(2:end)];
zr = [z(1:end-1); z(1:end-1) + w(1:end-1); z(2:end) + w(2:end); z(2:end)];

%plot the regions with no edges
h = patch(xr,yr,zr,c, 'LineStyle','none', varargin{:});
...