Преобразуйте массивы 1D в формат сетки - PullRequest
0 голосов
/ 06 июля 2018

У меня есть данные x, y, z и v, организованные как векторы столбцов. Аналогичные данные можно получить с помощью кода ниже:

N = 5;
[xf,yf,zf,vf] = flow(N);
ux = unique(xf);
uy = unique(yf);
uz = unique(zf);

x = nan(numel(xf),1);
y = nan(numel(yf),1);
z = nan(numel(zf),1);
v = nan(numel(vf),1);
iCount = 1;
for iX = 1:numel(ux)
    for iY = 1:numel(uy)
        for iZ = 1:numel(uz)
            x(iCount) = ux(iX);
            y(iCount) = uy(iY);
            z(iCount) = uz(iZ);
            v(iCount) = vf((xf == x(iCount))&(yf == y(iCount))&(zf == z(iCount)));
            iCount = iCount+1;
        end
    end
end

Я не смог изменить способ генерации данных, поэтому мне нужно изменить его, чтобы использовать позже с isosurface() и griddedInterpolant() позже. Размер исходных данных довольно большой, и я бы хотел избежать циклов. Простое использование функции reshape():

X = reshape(x,[N,2*N,N]);
Y = reshape(y,[N,2*N,N]);
Z = reshape(z,[N,2*N,N]);
V = reshape(v,[N,2*N,N]);
isosurface(X,Y,Z,V,-3)

показывает мне, что Input grid is not a valid MESHGRID.

Не могли бы вы помочь мне соответствующим образом изменить данные?

1 Ответ

0 голосов
/ 06 июля 2018

Порядок элементов в ваших массивах не совпадает с основным порядком столбца, полученным из meshgrid. Вы почти закончили, но вам нужно изменить форму ваших 1d массивов с другой формой, а затем преобразовать результат обратно в реальную форму, которая вам нужна:

N = 5;
[xf,yf,zf,vf] = flow(N);
ux = unique(xf);
uy = unique(yf);
uz = unique(zf);

x = nan(numel(xf),1);
y = nan(numel(yf),1);
z = nan(numel(zf),1);
v = nan(numel(vf),1);
iCount = 1;
for iX = 1:numel(ux)
    for iY = 1:numel(uy)
        for iZ = 1:numel(uz)
            x(iCount) = ux(iX);
            y(iCount) = uy(iY);
            z(iCount) = uz(iZ);
            v(iCount) = vf((xf == x(iCount))&(yf == y(iCount))&(zf == z(iCount)));
            iCount = iCount+1;
        end
    end
end

% new stuff starts here
X = permute(reshape(x,[N,N,2*N]),[2,3,1]);
Y = permute(reshape(y,[N,N,2*N]),[2,3,1]);
Z = permute(reshape(z,[N,N,2*N]),[2,3,1]);
V = permute(reshape(v,[N,N,2*N]),[2,3,1]);

% check equivalence
isequal(X,xf)
isequal(Y,yf)
isequal(Z,zf)
isequal(V,vf)

Выше указано, что входные массивы воспроизводятся (мы получаем четыре логических 1 с).

Обратите внимание, что ваш тестовый пример должен быть немного более асимметричным, потому что теперь некоторые из входных массивов являются транспонированными друг для друга, а два из трех измерений имеют одинаковый размер. Если ваш тест с асимметричными размерами, т. Е. [N,M,K], гораздо проще выяснить возможные неоднозначности, поскольку в этом случае все измерения неэквивалентны:

N = 2; M = 3; K = 4;
[xf,yf,zf] = meshgrid(1:N,1:M,1:K);
vf = flow(xf,yf,zf);

ux = unique(xf);
uy = unique(yf);
uz = unique(zf);

x = nan(numel(xf),1);
y = nan(numel(yf),1);
z = nan(numel(zf),1);
v = nan(numel(vf),1);
iCount = 1;
for iX = 1:numel(ux)
    for iY = 1:numel(uy)
        for iZ = 1:numel(uz)
            x(iCount) = ux(iX);
            y(iCount) = uy(iY);
            z(iCount) = uz(iZ);
            v(iCount) = vf((xf == x(iCount))&(yf == y(iCount))&(zf == z(iCount)));
            iCount = iCount+1;
        end
    end
end

X = permute(reshape(x,[K,M,N]),[2,3,1]);
Y = permute(reshape(y,[K,M,N]),[2,3,1]);
Z = permute(reshape(z,[K,M,N]),[2,3,1]);
V = permute(reshape(v,[K,M,N]),[2,3,1]);

% check equivalence
isequal(X,xf)
isequal(Y,yf)
isequal(Z,zf)
isequal(V,vf)
...