我如何“膨胀”一个多边形?也就是说,我想做一些类似的事情:

要求是,新的(膨胀的)多边形的边/点与旧的(原始的)多边形的边/点的距离都是相同的(在示例图片上,它们不是,因为这样它就必须使用弧来膨胀顶点,但让我们暂时忘记这一点;))。

我要找的数学术语实际上是向内/向外多边形偏移。balint指出这一点+1。另一种命名是多边形缓冲。

我的搜索结果:

以下是一些链接:

多边形偏移策略综述 多边形偏移,问题 缓冲多边形数据


当前回答

我想我可以简单地提到我自己的多边形裁剪和偏移库- Clipper。

虽然Clipper主要是为多边形裁剪操作而设计的,但它也做多边形偏移。该库是用Delphi、c++和c#编写的开源免费软件。它有一个非常无限制的Boost许可证,允许它在免费软件和商业应用程序中免费使用。

多边形偏移可以使用三种偏移样式之一-方形,圆形和斜切。

2022年8月: Clipper2现在已经正式发布,它取代了Clipper(又名Clipper1)。

其他回答

我使用简单的几何:向量和/或三角学

在每个角求中向量和中角。中向量是由边角定义的两个单位向量的算术平均值。中角是边角的一半。 如果你需要扩展(或收缩)你的多边形的数量d从每条边;你应该向外(向内)乘以d/sin(中角)来得到新的角点。 对所有的角重复这个步骤

注意你的方向。使用定义角的三个点进行逆时针测试;找出哪条路是出去,哪条路是进去。

另一个选择是使用boost::polygon——文档有些缺乏,但你应该会发现resize和bloat方法,以及重载的+=操作符,它们实际上实现了缓冲。例如,增加一个多边形(或一组多边形)的大小可以像下面这样简单:

poly += 2; // buffer polygon by 2

有几个库可以使用(也可用于3D数据集)。

https://github.com/otherlab/openmesh https://github.com/alecjacobson/nested_cages http://homepage.tudelft.nl/h05k3/Projects/MeshThickeningProj.htm

您还可以找到这些库的相应出版物,以更详细地了解算法。

最后一个选项依赖最少,是自包含的,可以在.obj文件中读取。

每条线都应该将平面分割为“内部”和“轮廓”;你可以用常用的内积法求出来。

将所有的线向外移动一段距离。

考虑所有相邻直线对(直线,不是线段),求交点。这些是新的顶点。

清除新顶点通过删除任何交叉部分。我们这里有几个案子

(a)个案一:

 0--7  4--3
 |  |  |  |
 |  6--5  |
 |        |
 1--------2

如果你把它除以1,你会得到这个:

0----a----3
|    |    |
|    |    |
|    b    |
|         |
|         |
1---------2

7和4重叠。如果你看到这个,你去掉这个点和中间的所有点。

(b)情况2

 0--7  4--3
 |  |  |  |
 |  6--5  |
 |        |
 1--------2

如果你把它乘以2,你会得到这个:

0----47----3
|    ||    |
|    ||    |
|    ||    |
|    56    |
|          |
|          |
|          |
1----------2

为了解决这个问题,对于直线的每一段,你必须检查它是否与后面的段重叠。

(c)情况3

       4--3
 0--X9 |  |
 |  78 |  |
 |  6--5  |
 |        |
 1--------2

除以1。这是情况1的一般情况。

(d)情况4

与case3相同,但支出2。

实际上,如果你能处理情况4。所有其他的情况都是一些特殊的情况有一些直线或顶点重叠。

在情况4中,你保留一个顶点的堆栈。当你发现与后一条线重叠的线时,你就推,当你得到后一条线时,就弹出。就像你在凸船体中做的一样。

听起来你想要的是

Starting at a vertex, face anti-clockwise along an adjacent edge. Replace the edge with a new, parallel edge placed at distance d to the "left" of the old one. Repeat for all edges. Find the intersections of the new edges to get the new vertices. Detect if you've become a crossed polygon and decide what to do about it. Probably add a new vertex at the crossing-point and get rid of some old ones. I'm not sure whether there's a better way to detect this than just to compare every pair of non-adjacent edges to see if their intersection lies between both pairs of vertices.

生成的多边形位于所需的距离上,与旧多边形距离顶点“足够远”。在一个顶点附近,距离旧多边形d的点的集合,正如你所说,不是一个多边形,所以不能满足所述的要求。

我不知道这个算法是否有名字,网络上的示例代码,或者是一个残酷的优化,但我认为它描述了你想要的东西。