质心和质心的计算给出顶点时多面体的体积

时间:2013-01-06 21:17:24

标签: performance matlab volume centroid polyhedra

考虑到凸多面体(3D)的顶点的位置,我需要计算多面体的质心和体积。以下代码位于Mathworks site

function C = centroid(P)
k=convhulln(P);
if length(unique(k(:)))<size(P,1)
    error('Polyhedron is not convex.');
end
T = delaunayn(P);
n = size(T,1);
W = zeros(n,1);
C=0;
for m = 1:n
    sp = P(T(m,:),:);
    [null,W(m)]=convhulln(sp);
    C = C + W(m) * mean(sp);
end
C=C./sum(W);
return
end

代码很优雅,但速度非常慢。我需要数百次计算数千个多面体的体积和质心。在当前状态下使用此代码是不可行的。有没有人知道更好的方法,或者这个代码可以更快?我可以想到一些微小的变化,例如用表达式替换mean表示平均值。

3 个答案:

答案 0 :(得分:3)

有一种更简单的方法可以用最小的努力来计算音量。第一种风味使用多面体的3个局部拓扑信息集,边缘的切线单位矢量,该切线上的平面内法线的单位矢量和小平面本身的单位矢量(从中提取非常简单)顶点)。有关详细信息,请参阅Volume of a Polyhedron

第二种味道使用面部区域,法线向量和面部重心来根据此Wikipedia Article计算多面体体积。 两种算法都相当简单,易于实现,并且通过简单的求和结构也易于矢量化。我想这两种方法都比完全成熟的多面体细分快得多。

然后,可以通过应用发散定理来计算多面体的质心,该发散定理将整个多面体体积上的积分转移到多面体表面上的积分中。详细说明可在Calculating the volume and centroid of a polyhedron in 3d中找到。我没有检查多面体是否真的需要三角形的分割,或者也可以检查多面体的更复杂的多边形表面,但无论如何,面的曲面细分比体积细分要简单得多。 总的来说,这种组合方法应该比音量方法快得多。

答案 1 :(得分:1)

如果你需要精确的解决方案,那么如果quickhull不够好,请考虑你唯一的选择cudahull。虽然,即便如此,你最多只能增加40倍(看起来)。

我假设你制作的凸包每个都有至少10个顶点(如果它远小于那个,你可以做的不多)。如果你不介意“足够接近”的解决方案。您可以创建一个quickhull版本,以限制每个多边形的顶点数。限制计算的顶点数量也允许在需要时计算最大误差。

事实是,当凸包上的顶点数接近无穷大时,你最终会得到一个球体。这意味着由于快速船体的工作方式,您添加到凸包的每个附加顶点的效果*都比之前的要小。

*根据quickhull的编码方式,这可能仅在一般意义上是正确的。在实践中实现这一点需要修改quickhull的递归算法,因此虽然总是计算“下一个顶点”(除了在添加最后一个顶点之后,或者该部分没有剩余点),顶点实际上被添加到凸包中。最大化多面体体积增加的顺序(可能是从最远到最远的顺序)。为了跟踪添加顶点的顺序,你会产生一些性能成本,但只要待处理的凸包船点与待处理点的比率足够高,就应该值得。至于错误,最好的选择可能是在达到实际凸包时停止算法,或者最大增加到体积小于当前总体积的某一部分。如果性能更重要,那么只需限制每个多边形的凸包点数。

您还可以查看各种近似凸壳算法,但我上面概述的方法应该适用于体积/质心近似,并具有确定误差的能力。

答案 2 :(得分:0)

您可以加快代码的速度取决于您想要计算质心的方式。有关您的选项,请参阅this answer about centroid calculation。事实证明,如果你需要实心多面体的质心,你基本上就不走运了。但是,如果只有多面体的顶点有重量,那么你可以简单地写

[k,volume] = convhulln(P);
centroid = mean(P(k,:));
相关问题