簡體   English   中英

如何計算3維投影的面積?

[英]How do I calculate the area of a 3 dimensional projection?

例如,使用以下代碼,我有一個坐標矩陣,其中包含3個立方對象,每個對象由8個角定義,總共有24個坐標。 我對坐標進行旋轉,然后刪除y坐標以獲得xz平面中的投影。 如何計算這些立方體在xz平面中的面積,而忽略間隙並考慮重疊? 我嘗試使用polyarea ,但這似乎不起作用。

clear all
clc
A=[-100 -40 50
-100    -40 0
-120    -40 50
-120    -40 0
-100    5   0
-100    5   50
-120    5   50
-120    5   0
-100    0   52
-100    0   52
20  0   5
20  0   5
-100    50  5
-100    50  5
20  50  52
20  50  52
-30 70  53
-30 70  0
5   70  0
5   70  53
-30 120 53
-30 120 0
5   120 53
5   120 0]; %3 Buildings Coordinate Matrix
theta=60; %Angle
rota = [cosd(theta) -sind(theta) 0; sind(theta) cosd(theta) 0; 0 0 1]; %Rotation matrix
R=A*rota; %rotates the matrix
R(:,2)=[];%deletes the y column

第一步將使用convhull (如yar所建議 )來獲取每個投影多邊形區域的輪廓。 應該注意的是,這里要使用凸包,因為您要處理的是長方體,即長方體。 我認為您的第二個長方體(位於A(9:16, :) )的坐標中有錯誤,因此我將代碼修改為以下內容:

A = [-100   -40    50
     -100   -40     0
     -120   -40    50
     -120   -40     0
     -100     5     0
     -100     5    50
     -120     5    50
     -120     5     0
     -100     0    52
     -100     0     5
       20     0    52
       20     0     5
     -100    50     5
     -100    50    52
       20    50     5
       20    50    52
      -30    70    53
      -30    70     0
        5    70     0
        5    70    53
      -30   120    53
      -30   120     0
        5   120    53
        5   120     0];
theta = 60;
rota = [cosd(theta) -sind(theta) 0; sind(theta) cosd(theta) 0; 0 0 1];
R = A*rota;

您可以生成多邊形輪廓並將其可視化,如下所示:

nPerPoly = 8;
nPoly = size(R, 1)/nPerPoly;
xPoly = mat2cell(R(:, 1), nPerPoly.*ones(1, nPoly));
zPoly = mat2cell(R(:, 3), nPerPoly.*ones(1, nPoly));
C = cell(1, nPoly);
for iPoly = 1:nPoly
  P = convhull(xPoly{iPoly}, zPoly{iPoly});
  xPoly{iPoly} = xPoly{iPoly}(P);
  zPoly{iPoly} = zPoly{iPoly}(P);
  C{iPoly} = P([1:end-1; 2:end].')+nPerPoly.*(iPoly-1);  % Constrained edges, needed later
end

figure();
colorOrder = get(gca, 'ColorOrder');
nColors = size(colorOrder, 1);
for iPoly = 1:nPoly
  faceColor = colorOrder(rem(iPoly-1, nColors)+1, :);
  patch(xPoly{iPoly}, zPoly{iPoly}, faceColor, 'EdgeColor', faceColor, 'FaceAlpha', 0.6);
  hold on;
end
axis equal;
axis off;

這是情節:

在此處輸入圖片說明

如果你想計算每個多邊形投影的面積,把它們加起來那將是非常容易的:只要改變上述循環捕捉和總結,從呼叫第二輸出convexhull

totalArea = 0;
for iPoly = 1:nPoly
  [~, cuboidArea] = convhull(xPoly{iPoly}, zPoly{iPoly});
  totalArea = totalArea+cuboidArea;
end

但是 ,如果需要多邊形並的面積,則必須考慮重疊部分。 您有幾種選擇。 如果具有“ 映射工具箱”,則可以使用函數polybool獲取輪廓,然后使用polyarea計算其面積。 您還可以在MathWorks File Exchange上找到一些實用程序(例如thisthis )。 在這里,我將向您展示另一個使用delaunayTriangulation替代方法。 首先,我們可以使用上面創建的邊緣約束C來創建投影點的三角剖分時使用:

oldState = warning('off', 'all');
DT = delaunayTriangulation(R(:, [1 3]), vertcat(C{:}));
warning(oldState);

這將自動在約束邊相交的地方創建新的頂點。 不幸的是,它還將對所有點的凸包執行三角剖分,填充我們不希望填充的點。 這是三角剖分的樣子:

figure();
triplot(DT, 'Color', 'k');
axis equal;
axis off;

在此處輸入圖片說明

現在,我們必須確定不需要的多余三角形並將其刪除。 我們可以通過找到每個三角形的質心並使用inpolygon來測試它們是否在我們每個單獨的長方體投影的所有3個范圍之外,來做到這一點。 然后,我們可以計算剩余三角形的面積,並使用polyarea ,得出投影的總面積:

dtFaces = DT.ConnectivityList;
dtVertices = DT.Points;
meanX = mean(reshape(dtVertices(dtFaces, 1), size(dtFaces)), 2);
meanZ = mean(reshape(dtVertices(dtFaces, 2), size(dtFaces)), 2);
index = inpolygon(meanX, meanZ, xPoly{1}, zPoly{1});
for iPoly = 2:nPoly
  index = index | inpolygon(meanX, meanZ, xPoly{iPoly}, zPoly{iPoly});
end
dtFaces = dtFaces(index, :);
xUnion = reshape(dtVertices(dtFaces, 1), size(dtFaces)).';
yUnion = reshape(dtVertices(dtFaces, 2), size(dtFaces)).';
totalArea = sum(polyarea(xUnion, yUnion));

此示例的總面積為:

totalArea =

     9.970392341143055e+03

注意:上面的代碼已被概括為任意數量的長方體。

polyarea是正確的處理方法,但是您需要在每個投影的凸包上調用它。 否則,您的投影中心將具有點,結果將不是“簡單”多邊形。

暫無
暫無

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

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