简体   繁体   English

如何计算3维投影的面积?

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

For example, using the following code, I have a coordinate matrix with 3 cubical objects defined by 8 corners each, for a total of 24 coordinates. 例如,使用以下代码,我有一个坐标矩阵,其中包含3个立方对象,每个对象由8个角定义,总共有24个坐标。 I apply a rotation to my coordinates, then delete the y coordinate to obtain a projection in the xz plane. 我对坐标进行旋转,然后删除y坐标以获得xz平面中的投影。 How do I calculate the area of these cubes in the xz plane, ignoring gaps and accounting for overlap? 如何计算这些立方体在xz平面中的面积,而忽略间隙并考虑重叠? I have tried using polyarea , but this doesn't seem to work. 我尝试使用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

The first step will be to use convhull (as yar suggests ) to get an outline of each projected polygonal region. 第一步将使用convhull (如yar所建议 )来获取每个投影多边形区域的轮廓。 It should be noted that a convex hull is appropriate to use here since you are dealing with cuboids, which are convex objects. 应该注意的是,这里要使用凸包,因为您要处理的是长方体,即长方体。 I think you have an error in the coordinates for your second cuboid (located in A(9:16, :) ), so I modified your code to the following: 我认为您的第二个长方体(位于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;

And you can generate the polygonal outlines and visualize them like so: 您可以生成多边形轮廓并将其可视化,如下所示:

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;

And here's the plot: 这是情节:

在此处输入图片说明

If you wanted to calculate the area of each polygonal projection and add them up it would be very easy: just change the above loop to capture and sum the second output from the calls to convexhull : 如果你想计算每个多边形投影的面积,把它们加起来那将是非常容易的:只要改变上述循环捕捉和总结,从呼叫第二输出convexhull

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

However , if you want the area of the union of the polygons, you have to account for the overlap. 但是 ,如果需要多边形并的面积,则必须考虑重叠部分。 You have a few alternatives. 您有几种选择。 If you have the Mapping Toolbox then you could use the function polybool to get the outline, then use polyarea to compute its area. 如果具有“ 映射工具箱”,则可以使用函数polybool获取轮廓,然后使用polyarea计算其面积。 There are also utilities you can find on the MathWorks File Exchange (such as this and this ). 您还可以在MathWorks File Exchange上找到一些实用程序(例如thisthis )。 I'll show you another alternative here that uses delaunayTriangulation . 在这里,我将向您展示另一个使用delaunayTriangulation替代方法。 First we can take the edge constraints C created above to use when creating a triangulation of the projected points: 首先,我们可以使用上面创建的边缘约束C来创建投影点的三角剖分时使用:

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

This will automatically create new vertices where the constrained edges intersect. 这将自动在约束边相交的地方创建新的顶点。 Unfortunately, it will also perform the triangulation on the convex hull of all the points, filling in spots that we don't want filled. 不幸的是,它还将对所有点的凸包执行三角剖分,填充我们不希望填充的点。 Here's what the triangulation looks like: 这是三角剖分的样子:

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

在此处输入图片说明

We now have to identify the extra triangles we don't want and remove them. 现在,我们必须确定不需要的多余三角形并将其删除。 We can do this by finding the centroids of each triangle and using inpolygon to test if they are outside all 3 of our individual cuboid projections. 我们可以通过找到每个三角形的质心并使用inpolygon来测试它们是否在我们每个单独的长方体投影的所有3个范围之外,来做到这一点。 We can then compute the areas of the remaining triangles and sum them up using polyarea , giving us the total area of the projection: 然后,我们可以计算剩余三角形的面积,并使用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));

And the total area for this example is: 此示例的总面积为:

totalArea =

     9.970392341143055e+03

NOTE: The above code has been generalized for an arbitrary number of cuboids. 注意:上面的代码已被概括为任意数量的长方体。

polyarea is the right way to go, but you need to call it on the convex hull of each projection. polyarea是正确的处理方法,但是您需要在每个投影的凸包上调用它。 If not, you will have points in the centers of your projections and the result is not a "simple" polygon. 否则,您的投影中心将具有点,结果将不是“简单”多边形。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM