簡體   English   中英

在 MATLAB 中細分 3D 表面

[英]Subdividing a 3D surface in MATLAB

我正在使用 MATLAB 創建一些圖表來解釋我的研究,但遇到了以下問題。 我已經創建了一個繞 x 軸旋轉的半橢球,但我想演示橢球內的一些內部結構,它將繞 x 軸和 y 軸旋轉。 這大致如下圖所示,我將橢球細分為四個部分(用我糟糕的繪畫技巧)。

在此處輸入圖片說明

如何使用圍繞 x 軸和 y 軸的不同旋轉平面將我的橢球細分為多個部分? 我可以創建橢圓體和相交平面,但從那里我不知道如何划分橢圓體並改變面部顏色。

我在下面包含了一些基本代碼來開始工作。 我原以為我可以像將橢圓體切成兩半一樣掩蓋橢圓體坐標的一部分,但這不起作用。 我猜我需要制作某種網格,但我不知道如何將相交表面和橢圓體的網格組合起來。

figure
x   = 0;    y   = 0;    z   = 0;
tl  = 10;   tw  = 4;   td  = 2;

% Create ellipsoid
[ex,ey,ez]  = ellipsoid(x, y, z, tl, tw, td,40);
ex          = ex(1:ceil(length(ez)/2),:);   % Remove top half 
ey          = ey(1:ceil(length(ez)/2),:);   % of ellipsoid
ez          = ez(1:ceil(length(ez)/2),:);

% Make some planes
[ySL,zSL] = meshgrid([-10:10],[-2:0.2:2]);
xSL1 = zeros(size(ySL, 1)); % Generate z data
hSL1 = surf(xSL1,ySL,zSL);

hold on
[ySL,zSL] = meshgrid([-10:10],[-3:0.2:1]);
xSL2 = ones(size(ySL, 1)); % Generate z data
hSL2 = surf(xSL2,ySL,zSL);

% rotate(hSL,[1 0 0],5);
rotate([hSL1 hSL2],[0 1 0],-70);

hSurf1  = surf(ex,ey,ez);
set([hSurf1 hSL1 hSL2],'facecolor','blue','facealpha',.2,...
    'edgecolor','none')

% Plot settings
daspect([1 1 0.3]);
hold off
view(-10,6)

任何幫助是極大的贊賞,

這是一個有趣的問題。 因此,這里有一個解決方案,用於 1) 在橢圓內繪制三個以兩個平面為邊界的點,以及 2) 將這些點形成一個平滑的補丁表示。

我的基本想法是構建一個覆蓋(根據需要盡可能密集)整個感興趣的 XYZ 空間的網格。 然后我要做的是以參數形式ax+by+cz+d=0定義兩個平面 這些是要在其間繪制數據的平面。 使用平面的法向量,以及每個平面上的一個點的信息,我可以使用點積推斷 XYZ 網格中的每個點是在平面上方還是下方:如果點積小於零,則點在平面上方,如果大於零,則在平面上方。

使用 邏輯索引,我然后找到網格上的哪些點滿足條件 1) 在平面 1 之上,2) 在平面 2 之下,和 3) 在橢球內和 -- 可選 -- 4) 在Z=0之下。

最后,我繪制了橢圓體和平面,以及滿足上述標准的點。

在這種情況下,我定義了兩個平面,但我想您可以為任意數量的平面執行此操作。 代碼又快又臟,但希望能給你一個前進的方向!

% Define the ellipse
x   = 0;    y   = 0;    z   = 0;
tl  = 10;   tw  = 4;   td  = 2;

% Create ellipsoid
[ex,ey,ez]  = ellipsoid(x, y, z, tl, tw, td,40);
ex          = ex(1:ceil(length(ez)/2),:);   % Remove top half 
ey          = ey(1:ceil(length(ez)/2),:);   % of ellipsoid
ez          = ez(1:ceil(length(ez)/2),:);


% Define a 3D grid over area of interest
xx = linspace(min(ex(:)),max(ex(:)),50);
yy = linspace(min(ey(:)),max(ey(:)),50);
zz = linspace(min(ez(:)),max(ez(:)),50);
[X, Y, Z] = meshgrid(xx, yy, zz);
V = [X(:) Y(:) Z(:)]; % rearrange

% Define two planes (ax + bx + cz + d = 0)
a = [0; 0];
b = [-1; 1];
c = [-1; 1];
d = [-1; -1];
% Normal vectors of the planes
n = [a b c];
n(1,:) = n(1,:) / norm(n(1,:));
n(2,:) = n(2,:) / norm(n(2,:));

% Find a point (0,0,z) on each plane
zp = [zeros(2) (d- a * 0 - b * 0)./c];

% Define the area of interest.
% Dot product to test if grid points are below or above the planes
% We want: above plane 1, below plane 2.
V1 = sum(bsxfun(@times, bsxfun(@minus, V, -zp(1,:)), n(1,:)),2);
V2 = sum(bsxfun(@times, bsxfun(@minus, V, -zp(2,:)), n(2,:)),2);
between_planes = (V1 < 0) & (V2 < 0);
% ...and the points have to be inside the ellipsoid
in_ellipse = ((X(:) - x)/tl).^2 + ((Y(:)-y)/tw).^2 + ((Z(:)-z)/td).^2 < 1;
% Final AOI
aoi = between_planes & in_ellipse;

% Add this if you want to also have only values with Z < 0
aoi = aoi & (V(:,3) < 0);

figure;
surf(ex, ey, ez, 'facecolor','blue','facealpha',.2,...
    'edgecolor','none')

所以,現在我們准備繪制一些數據! 首先,讓我們嘗試繪制網格以獲得一種顯示單個數據點的離散可視化:

hold on;
plot3(V(aoi,1), V(aoi, 2), V(aoi, 3), 'r.')

...只是為了看看它是否有效,讓我們將我們之前定義的平面添加到可視化中。 這是您最終可能想要擺脫的東西。

% Draw the planes
[X,Y] = meshgrid(xx,yy);
Z = cell(2,1);
clr = {'r', 'g'};
for k = 1:2
    Z{k} = (a(k) * X + b(k) * Y + d(k))/ (-c(k));
    hs(k) = surf(xx, yy, Z{k},'facecolor',clr{k}, 'facealpha',.2, 'edgecolor','none');
    drawnow;
end
view([-115 10])
legend(hs, 'Plane 1 (above)', 'Plane 2 (below');

好吧,最后,如果我們想顯示一些平滑的數據,我們可以使用alphaShape從我們擁有的這些數據點中提取多面體。 我們可以通過使用plot將多面體可視化為patch對象。 最后,我們可以為補丁中的每個頂點分配我們想要的任何顏色,通過設置'Facecolor'屬性為可視化顏色設置平滑變化,並通過將'EdgeColor'設置為'none'來刪除討厭的頂點邊緣:

% Moving on to smooth representation...
shp = alphaShape(V(aoi,1), V(aoi, 2), V(aoi, 3),1);
hs = plot(shp);
% Create a colormap to use for the patch (color of each vertex)
cmap = jet(size(hs.Vertices,1));
set(hs, 'FaceVertexCData', cmap);
set(hs, 'FaceColor', 'interp'); % smooth interp coloring
set(hs, 'EdgeColor', 'none'); % Remove ugly edges

就是這樣了。 剩下的就是用適合您的數據的任何值替換頂點顏色值。 此外,如果您不希望這些數據點沿着補丁顯示在顯示中,請記住提前跳過plot3部分。

下面的示例最終結果,也顯示了兩個平面。 最終結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM