Как создать трехмерную поверхность из изолиний?
У меня есть набор точек изолинии (или точек контура), например:
http://www.rcad.eu/triang&isolines%20example1.jpg
Каждая точка изолинии имеет свои соответствующие координаты X, Y и Z. Поскольку они являются изолинии, это означает, что каждая точка будет иметь уникальную пару XY, но точки на одной линии будут иметь одинаковую координату Z.
Теперь, есть ли какой-нибудь алгоритм или какие-либо программные пакеты (в C# или C++ или MATLAB), которые я могу использовать для интерполяции точек изолинии в полную трехмерную поверхность?
P / S: я не просто заинтересован в конечном результате, я заинтересован в получении данных интерполированной поверхности, чтобы я мог построить поверхность самостоятельно.
Изменить: C++ решения также приветствуются.
4 ответа
В MATLAB вы можете использовать любую функцию griddata
или TriScatteredInterp
класс (Примечание: по состоянию на R2013a scatteredInterpolant
является рекомендуемой альтернативой). Оба из них позволяют вам подгонять поверхность данных с регулярным интервалом к набору точек с неравномерным интервалом (хотя это выглядит griddata
больше не рекомендуется в новых версиях MATLAB). Вот как вы можете использовать каждый:
griddata
:[XI,YI,ZI] = griddata(x,y,z,XI,YI)
где
x,y,z
каждый представляет векторы декартовых координат для каждой точки (в данном случае это точки на контурных линиях). Вектор строкиXI
и вектор столбцаYI
являются декартовыми координатами, при которыхgriddata
интерполирует значенияZI
подогнанной поверхности. Новые значения, возвращаемые для матрицXI,YI
такие же как результат прохожденияXI,YI
вmeshgrid
создать единую сетку точек.TriScatteredInterp
учебный класс:[XI,YI] = meshgrid(...); F = TriScatteredInterp(x(:),y(:),z(:)); ZI = F(XI,YI);
где
x,y,z
снова представляют векторы декартовых координат для каждой точки, только на этот раз я использовал операцию изменения формы двоеточия(:)
чтобы убедиться, что каждый является вектором столбца (необходимый формат дляTriScatteredInterp
). ИнтерполантF
Затем оценивается с использованием матрицXI,YI
что вы должны создать с помощьюmeshgrid
,
Пример и сравнение
Вот пример кода и полученный рисунок, который он генерирует для восстановления поверхности по данным контура, используя оба метода выше. Данные контура были сгенерированы с contour
функция:
% First plot:
subplot(2,2,1);
[X,Y,Z] = peaks; % Create a surface
surf(X,Y,Z);
axis([-3 3 -3 3 -8 9]);
title('Original');
% Second plot:
subplot(2,2,2);
[C,h] = contour(X,Y,Z); % Create the contours
title('Contour map');
% Format the coordinate data for the contours:
Xc = [];
Yc = [];
Zc = [];
index = 1;
while index < size(C,2)
Xc = [Xc C(1,(index+1):(index+C(2,index)))];
Yc = [Yc C(2,(index+1):(index+C(2,index)))];
Zc = [Zc C(1,index).*ones(1,C(2,index))];
index = index+1+C(2,index);
end
% Third plot:
subplot(2,2,3);
[XI,YI] = meshgrid(linspace(-3,3,21)); % Generate a uniform grid
ZI = griddata(Xc,Yc,Zc,XI,YI); % Interpolate surface
surf(XI,YI,ZI);
axis([-3 3 -3 3 -8 9]);
title('GRIDDATA reconstruction');
% Fourth plot:
subplot(2,2,4);
F = TriScatteredInterp(Xc(:),Yc(:),Zc(:)); % Generate interpolant
ZIF = F(XI,YI); % Evaluate interpolant
surf(XI,YI,ZIF);
axis([-3 3 -3 3 -8 9]);
title('TriScatteredInterp reconstruction');
Обратите внимание, что между этими двумя результатами есть небольшая разница (по крайней мере, в этом масштабе). Также обратите внимание, что интерполированные поверхности имеют пустые области вблизи углов из-за разреженности данных контура в этих точках.
Вы можете использовать инструмент gridfit, найденный на центральном файловом обмене MATLAB. Один из примеров, которые я привожу, - это именно то, что вы хотите сделать, начиная со списка точек, взятых из изолиний, я реконструирую гладкую поверхность по данным. Фактически, пример, который я использовал, был взят с топографической карты.
Я думаю, что то, что вы хотите, называется "Контурная сшивка", например, обсуждается в этой статье.
В MATLAB есть встроенная команда SURF, которая принимает три массива для X,Y,Z и строит график поверхности. Это может быть то, что вы ищете.