CGAL笔记之单元格复合体和多面体篇——多面体凸分解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

CGAL笔记之单元格复合体和多面体篇——多面体凸分解


1 介绍

对于非凸多面体的许多应用,有一个有效的解决方案,首先将多面体分解为凸块。例如,两个多面体的闵可夫斯基和可以通过将两个多面体分解为凸块,计算凸块的成对闵可夫斯基和,并合并成对和来计算。

虽然我们希望分解为最少数量的片段,但这个问题已知是NP-hard[1]。我们的实现将一个Nef多面体N分解为O(r2)个凸块,其中r是具有两个相邻切面的边的数量,这些相邻切面与多面体内部的夹角大于180度。这些边也被称为反射边。O(r2)个凸块的界为最差情况最优[1]。

在这里插入图片描述

基于垂直切面插入的垂直分解(从顶部查看)。左:非凸多面体。中:非垂直反射边缘已被解决。右图:垂直反射边缘已经被解决了。子体是凸的。

我们的分解分为两步。在第一步中,每个非垂直反射边e通过插入垂直facet e来解决。在第二步中,我们对垂直反射边做同样的处理。图中说明了这两个步骤。目前实现仅限于有界多面体的分解。

2 接口使用

Nef_polyhedron_3实例表示将三维空间细分为顶点、边、面和体。其中一些项形成多面体(已选),而另一些项表示多面体内的外部体积或孔(未选)。例如,单位立方体是点集[0,1]3。表示单位立方体的最小细分有8个顶点、12条边、6个面和2个体。由顶点、边和面包围的体积是立方体的内部,因此被选中。多维数据集外的卷不属于它,因此未被选择。顶点、边和面(也表示为边界项)用于分隔两个卷,但对于表示拓扑属性也很有用。对于(封闭的)单位立方体,边界项是多面体的一部分,因此被选中,但对于开放的单位立方体[0,1)3,它们不被选中。每个项目都有自己的选择标记,这允许正确表示Nef多面体,这些多面体在布尔和拓扑操作下关闭。

通常,Nef_polyhedron_3实例不包含任何冗余项。然而,函数convex_decomposition_3()将给定Nef_polyhedron_3的选定体细分为选定的facet。因此,这些额外的facet是多余的,也就是说,它们的插入改变了多面体的表示,而不是多面体本身。

当convex_decomposition_3()解析所有反射边时,所选的子体已成为凸体。它们中的每一个都由一个单独的体表示,因此可以分别遍历,如分解shell部分所述。访问凸块的另一种可能性是将它们转换为单独的Nef多面体,如下面的示例代码所示。

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/IO/Nef_polyhedron_iostream_3.h>
#include <CGAL/Nef_3/SNC_indexed_items.h>
#include <CGAL/convex_decomposition_3.h>
#include <list>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron_3;
typedef CGAL::Nef_polyhedron_3<Kernel, CGAL::SNC_indexed_items> Nef_polyhedron_3;
typedef Nef_polyhedron_3::Volume_const_iterator Volume_const_iterator;
int main() {
  Nef_polyhedron_3 N;
  std::cin >> N;
  CGAL::convex_decomposition_3(N);
  std::list<Polyhedron_3> convex_parts;
  // the first volume is the outer volume, which is
  // ignored in the decomposition
  Volume_const_iterator ci = ++N.volumes_begin();
  for( ; ci != N.volumes_end(); ++ci) {
    if(ci->mark()) {
      Polyhedron_3 P;
      N.convert_inner_shell_to_polyhedron(ci->shells_begin(), P);
      convex_parts.push_back(P);
    }
  }
  std::cout << "decomposition into " << convex_parts.size() << " convex parts " << std::endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值