我怎么会"膨胀"的一面?这就是我想要做的事类似于这样的:

alt text

要求是,新的(膨胀)面的边缘点都是在同一定距离的旧(原)面的(在本例中的图片,他们不是,自那时以来,它就会有使用弧膨胀的顶点,但是让我们忘了,现在)).

数学期我在寻找什么是实际上 向内/外侧面抵消.+1到巴林特指出了这一点。替代性命名 多边缓冲.

结果我的搜索:

这里有一些链接:

有帮助吗?

解决方案

我以为我可以简要地提及我自己的 多边裁剪和抵消库 - 帆船.

同时 帆船 是主要设计用于多边剪切运作,它面抵消。图书馆 开放源码软件 写在 德尔福、C++和C#.它有一个非常未支配经费余额 提高 许可证允许它可以用在这两种免费软件和商业应用不收费。

多边形的抵销可使用执行一个三个抵消风格方和斜接.

Polygon offsetting styles

其他提示

面你正在寻找被称为 向内/外侧偏移的多边形 在几何计算它是密切相关 直骨架.

这些都是几个抵消面对的一个复杂的多边形:

这是直框架的另一面:

如指出的其他意见,以及,取决于如何你计划的"膨胀/通缩"多边形可以结束了不同的连接的输出。

从计算的观点:一旦你已经直骨架应该能够建造的偏移的多边形的相对容易。开放源码和(免费为非商业的) CGAL 图书馆拥有包落实这些结构。看看 这个代码的例子 计算偏面使用CGAL.

封装手册 应该给你一个很好的起点,在如何建立这些结构甚至如果你不打算使用CGAL,并包含参考文件的数学定义和性质:

CGAL手册:2D觉骨骼和面抵消了

我听起来就像你想要什么是:

  • 开始在一个顶点,面对抗沿顺时针的一个相邻的边缘。
  • 代替边缘有一个新的、平行的边放置在距离 d 向"留"的旧的。
  • 重复为所有的边缘。
  • 找到交叉点的新的边缘,获得新的顶点。
  • 检测,如果你已经成为一个交叉面,并决定该怎么做的。或许添加一个新的顶点,在过境点和摆脱一些旧的。我不确定是否有一个更好的方法以检测,这不仅仅是比较每一个对非相邻的边缘看到,如果他们的交叉点在于两者之间的对折点。

得到的面在于在所要求的距离从旧的多边形"远远不够"从顶点。附近的一个顶点,该集点的距离 d 从旧面是,正如你所说,不是一个面,因此要求说明不能实现。

我不知道,如果这种算法有一个名字,例码网络,或者一个魔王的优化,但我觉得这描述了你想要什么。

对于这些类型的事我通常会使用 执照的正规会计事务所.为了示范的目的,我创造了这个 jsFiddle 使用 JSTS (JavaScript港口执照的正规会计事务所).你只需要转换的坐标你必须JSTS坐标:

function vectorCoordinates2JTS (polygon) {
  var coordinates = [];
  for (var i = 0; i < polygon.length; i++) {
    coordinates.push(new jsts.geom.Coordinate(polygon[i].x, polygon[i].y));
  }
  return coordinates;
}

结果是这样的:

enter image description here

额外的信息:我通常使用这种类型的充/放气(一个小小的修改我的目的),用于设置边界半径上面绘制的地图(用小册子或谷歌地图)。你只要转换(纬度、液化天然气)对JSTS坐标和其他的一切都是相同的。例如:

enter image description here

每个线应分的飞机到"内部"和"概述";你可以找到这个了使用通常的内产品的方法。

将所有的线外的一些距离。

考虑到所有对邻线(线、无线段),发现交汇点。这些都是新的顶点。

清理新的顶点,通过删除任何交叉部分。-我们有一些情况下这里

(a)案例1:

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

如果你把这个接一个,你得到了这一点:

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

7和4的重叠..如果你看到这个,你删除这点和所有有点之间。

(b)情况2

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

如果你把它通过两个,你得到这个:

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

要解决这一问题,对于每个分段的路线,你要检查它是否重叠与后一段。

(c)的情况3

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

花费1。这是一个更普遍的情况下对案1中。

(d)的情况4

同case3,但花费的两个。

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

要做到4的情况下,则保持一堆顶点..你把当你找到线的重叠与后一行,把它当你得到后者线。-就像你做什么在凸船体。

这里是一个替代解决方案中,看到如果你这样更好。

  1. 做一个 三角测量, 它不必是德洛内--的任何三角测量会怎么做。

  2. 膨胀每个三角形--这应该是微不足道的。如果存储三角形的抗顺时针的顺序,只要移动线路的右手边和做交叉口。

  3. 把它们合并使用改进的 Weiler-Atherton幅算法

在地理信息系统世界,一个使用负缓冲这个任务:http://www-users.cs.umn.edu/~npramod/enc_pdf.pdf

执照的正规会计事务所图书馆 应该为你做这个。请参阅文件的缓冲器操作: http://tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/operation/buffer/package-summary.html

对于一个粗略的概述,另见开发商指南:http://www.vividsolutions.com/jts/bin/JTS%20Developer%20Guide.pdf

大感谢安格斯*约翰逊为他的帆船库。有很好的代码样做的剪切东西的帆船主页 http://www.angusj.com/delphi/clipper.php#code 但是我没有看到一个实例对于面抵消。所以我想这也许是使用对于个人,如果我后我的代码:

    public static List<Point> GetOffsetPolygon(List<Point> originalPath, double offset)
    {
        List<Point> resultOffsetPath = new List<Point>();

        List<ClipperLib.IntPoint> polygon = new List<ClipperLib.IntPoint>();
        foreach (var point in originalPath)
        {
            polygon.Add(new ClipperLib.IntPoint(point.X, point.Y));
        }

        ClipperLib.ClipperOffset co = new ClipperLib.ClipperOffset();
        co.AddPath(polygon, ClipperLib.JoinType.jtRound, ClipperLib.EndType.etClosedPolygon);

        List<List<ClipperLib.IntPoint>> solution = new List<List<ClipperLib.IntPoint>>();
        co.Execute(ref solution, offset);

        foreach (var offsetPath in solution)
        {
            foreach (var offsetPathPoint in offsetPath)
            {
                resultOffsetPath.Add(new Point(Convert.ToInt32(offsetPathPoint.X), Convert.ToInt32(offsetPathPoint.Y)));
            }
        }

        return resultOffsetPath;
    }

另一个选择是使用 提升::多边形 -该文件有所欠缺,但你应该找到方法 resizebloat, 和也超载 += 操作员,这实际上实现缓冲。因此,例如尺寸增大的多边(或一组多边形)通过一些值可以作为简单的:

poly += 2; // buffer polygon by 2

根据咨询意见@JoshO布赖恩,它会出现的 rGeos 包在 R 语言实现了这种算法。看看 rGeos::gBuffer .

有一对夫妇的图书馆一个可以使用(也可用于3D数据集的).

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

其中一个还可以找到相应的出版物,这些图书馆以理解的算法更详细的说明。

最后一个拥有最少的依赖关系,是独立的,并可以阅读。obj文件。

最良好的祝愿, 斯蒂芬

我使用简单几何形状:向量和/或三角

  1. 在每一个角落查找中的矢量,以及中期角度。中矢量的算术平均值的两个单位矢量定义的边缘的角落。中期角度是一半的角度定义的边缘。

  2. 如果你需要扩大(或协定)多边形数额的d从各个边缘;你应该出去(在)过量d/sin(midAngle)获得新的角点。

  3. 重复,这对于所有角落

***以小心你的方向。让逆时针方向测试使用了三个指定的角落;要找出哪方式是出,或在。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top