Я пытаюсь построить трехмерный график поверхности для следующего уравнения t_t <= (xi_i - xi_j) . кврт(ро). Я включил свой код. Но я хотел бы отметить или заштриховать область под графиком этого поверхностного участка. Как мне это решить?
[X,Y] = meshgrid(1:0.5:10,1:20);
Z = X.* sqrt(Y);
figure;
colormap(jet)
surf(X,Y,Z)
colorbar
xlabel('Distance between two spatial points \xi_i & \xi_j (\xi_i - \xi_j)');
ylabel('Density(\rho)');
zlabel('Transmission Delay (t_t)');
@AnderBiguri Привет. Спасибо за ответ. Но я не ищу команду серфинга. Я ищу что-то вроде этого imgur.com/O1gDzDv . Но я редактировал с помощью 3D Paint. Есть ли какая-нибудь команда Matlab, которая отметит область под этой кривой?
Единственный способ, которым я могу думать, - это зацикливаться на краях и заполнять их соответствующим образом.
[X,Y] = meshgrid(1:0.5:10,1:20);
Z = X.* sqrt(Y);
figure;
p=parula; % please do not use jet :(
surf(X,Y,Z)
hold on;
%XZ init
for ii=1:size(Z,2)-1
patch([X(1,ii) X(1,ii+1) X(1,ii+1) X(1,ii)],...
[Y(1,1) Y(1,1) Y(1,1) Y(1,1)],...
[0 0 Z(1,ii+1) Z(1,ii) ],[p(1,:)]);
end
%XZ end
for ii=1:size(Z,2)-1
patch([X(end,ii) X(end,ii+1) X(end,ii+1) X(end,ii)],...
[Y(end,1) Y(end,1) Y(end,1) Y(end,1)],...
[0 0 Z(end,ii+1) Z(end,ii) ],[p(1,:)]);
end
%YZ init
for ii=1:size(Z,1)-1
patch([X(1,1) X(1,1) X(1,1) X(1,1)],...
[Y(ii,1) Y(ii+1,1) Y(ii+1,1) Y(ii,1)],...
[0 0 Z(ii+1,1) Z(ii,1) ],[p(1,:)]);
end
%YZ end
for ii=1:size(Z,1)-1
patch([X(1,end) X(1,end) X(1,end) X(1,end)],...
[Y(ii,end) Y(ii+1,end) Y(ii+1,end) Y(ii,end)],...
[0 0 Z(ii+1,end) Z(ii,end) ],[p(1,:)]);
end
colorbar
xlabel('Distance between two spatial points \xi_i & \xi_j (\xi_i - \xi_j)');
ylabel('Density(\rho)');
zlabel('Transmission Delay (t_t)');
Сейчас вы можете сделать множество вариантов стиля, например, удалить края или изменить цвета, которые я оставлю вам, поскольку их можно найти в Интернете.
Если это не совсем то, что вы хотели, это все еще в значительной степени способ сделать это. Используя patch
и соответствующие координаты.
Большое спасибо за помощь.
Вы можете добавить дополнительные поверхности, создав новый набор матриц для передачи в surf
с несколькими различными параметрами в зависимости от того, как вы хотите, чтобы результаты выглядели...
Если вы хотите просто заполнить стороны, вы можете добавить новую строку и столбец с каждой стороны ваших матриц следующим образом:
[R, C] = size(Z);
Xfill = [nan X(1, :) nan; X(:, [1 1:C C]); nan X(R, :) nan];
Yfill = [nan Y(1, :) nan; Y(:, [1 1:C C]); nan Y(R, :) nan];
Zfill = [nan zeros(1, C) nan; zeros(R, 1) Z zeros(R, 1); nan zeros(1, C) nan];
surf(Xfill, Yfill, Zfill);
view(-120, 30);
Это позволяет отображать поверхность и стороны одним вызовом surf
, что приводит к следующему результату:
Если вы также хотите заполнить нижнюю часть формы, вы можете обернуть поверхность вокруг и под собой, добавив новые столбцы, а затем добавить новую строку вверху и внизу, чтобы закрыть концы:
[R, C] = size(Z);
Xfill = [X(1, 1:C) nan(1, C+1); ... % Close top
X flip(X, 2) X(:, 1); ... % Flip data and connect to other side
X(R, 1:C) nan(1, C+1)]; % Close bottom
Yfill = [Y(1, 1:C) nan(1, C+1); ...
Y flip(Y, 2) Y(:, 1); ...
Y(R, 1:C) nan(1, C+1)];
Zfill = [zeros(1, C) nan(1, C+1); ...
Z zeros(R, C) Z(:, 1); ...
zeros(1, C) nan(1, C+1)];
surf(Xfill, Yfill, Zfill);
view(-120, -20);
Опять же, вы можете построить всю замкнутую поверхность одним вызовом surf
. Вот вид снизу, показывающий закрытое дно:
Когда вы рисуете все как один объект, вы ограничены, если хотите визуализировать стороны иначе, чем верх. Разделение объектов по сторонам, например Андер делает (используя patch
или отдельный вызов surf
), даст вам больше контроля над тем, как они окрашены по сравнению с верхней поверхностью. Чтобы создать единый объект поверхности для всех четырех сторон, вы можете извлечь записи по краям ваших матриц и реплицировать их по мере необходимости:
[R, C] = size(Z);
Xside = [1; 1]*[X(1, :) ... % Get first row
X(2:R, C).' ... % Get last column, without first row
X(R, (C-1):-1:1) ... % Get last row, without last column, flipped
X((R-1):-1:1, 1).']; % Get first column, without last row, flipped
Yside = [1; 1]*[Y(1, :) ...
Y(2:R, C).' ....
Y(R, (C-1):-1:1) ...
Y((R-1):-1:1, 1).'];
Zside = [Z(1, :) ...
Z(2:R, C).' ...
Z(R, (C-1):-1:1) ...
Z((R-1):-1:1, 1).'; ...
zeros(1, 2*(R+C)-3)];
surf(X, Y, Z); % Plot top surface
hold on;
surf(Xside, Yside, Zside, ... % Plot all four sides...
'EdgeColor', 'none', ... % with no edge coloring (i.e. grid)...
'FaceAlpha', 0.5); % and transparency
view(-120, 30);
И получившийся сюжет:
проще, чем у меня :D Я сделал другой, потому что мне было неясно, было ли это именно тем, чего хотел ОП, но если это так, то так
Спасибо за большую помощь. Это близко к тому, что я ищу. @AnderBiguri Извините за нечеткое описание.
@hkshks: Рад помочь! Просто проверяю ... ты хотел отметить мой ответ или ответ Хоки как принятый?
@gnovice Извините, мой плохой. Я новичок в этом сообществе. Я отметил ваш ответ как принятый. Во всяком случае, я не мог понять эту часть кодов. Xсторона = [1; 1]*[Х(1, :) Х(2:R, С).' ... X(R, (C-1):-1:1) X((R-1):-1:1, 1).']; Yсторона = [1; 1]*[Y(1, :) Y(2:R, C).' .... Y(R, (C-1):-1:1) Y((R-1):-1:1, 1).']; Zсторона = [Z(1, :) Z(2:R, C).' Z(R, (C-1):-1:1) Z((R-1):-1:1, 1).'; ... нули(1, 2*(R+C)-3)];
@hkshks: я добавил пару комментариев к этой части, чтобы сделать ее немного понятнее. По сути, вы просто обводите матрицы по периметру и собираете граничные значения. Часть [1; 1]*[...]
просто использует матричное умножение для репликации вектора-строки краевых значений и эквивалентна repmat([...], 2, 1)
.
Вот еще один способ использования patch
объектов.
Это решение очень похоже на решение Андера, но конструкция patch
обрабатывается по-другому, поэтому вам не нужно зацикливаться и в итоге обрабатывать только 4 объекта патчей.
%% Prepare domain limits
xLim = [1 10] ; xStep = 0.5 ;
yLim = [1 20] ; yStep = 1 ;
x = xLim(1):xStep:xLim(2) ;
y = yLim(1):yStep:yLim(2) ;
%% Your code
[X,Y] = meshgrid(x,y);
Z = X.* sqrt(Y);
figure;
surf(X,Y,Z)
colorbar
xlabel('Distance between two spatial points \xi_i & \xi_j (\xi_i - \xi_j)');
ylabel('Density(\rho)');
zlabel('Transmission Delay (t_t)');
%% prepare patch elements
zLim = [min(Z) max(Z)] ;
pcol = [0.2857,1,0.7143] ;
xface = [ x xLim(2) xLim(1) ] ;
yface = [ y yLim(2) yLim(1) ] ;
xface0 = zeros(size(xface)) ;
yface0 = zeros(size(yface)) ;
xfaceZ = [zeros(size(x)) zLim(1) zLim(1)] ;
yfaceZ = [zeros(size(y)) zLim(1) zLim(1)] ;
%% display the patches
hp(1) = patch( xface , xface0+yLim(1) , xfaceZ ,pcol ) ;
hp(3) = patch( xface , xface0+yLim(2) , xfaceZ ,pcol ) ;
hp(2) = patch( yface0+xLim(1) , yface , yfaceZ ,pcol ) ;
hp(4) = patch( yface0+xLim(2) , yface , yfaceZ ,pcol ) ;
%% update top edge of patches
% to connect to the surface edges
hp(1).ZData(1:end-2) = Z(1,:) ;
hp(2).ZData(1:end-2) = Z(:,1) ;
hp(3).ZData(1:end-2) = Z(end,:) ;
hp(4).ZData(1:end-2) = Z(:,end) ;
%% Color according to preferences
set(hp, 'Facecolor',pcol , 'FaceAlpha',0.5 , 'EdgeColor','none')
Будет отображать:
Спасибо за большую помощь.
Можете ли вы показать пример изображения того, что вы хотели бы? что-то вроде
surfc
?