【问题标题】:Algorithm to generate equally distributed points in a polygon在多边形中生成均匀分布点的算法
【发布时间】:2012-06-26 01:31:59
【问题描述】:

我正在寻找一种算法来在多边形内生成均匀分布的点。

这是场景:

我有一个多边形,由每个点的角 (x, y) 处的点的坐标指定。而且我有在多边形内生成的点数。

例如,假设我有一个包含 5 个点的多边形: (1, 1) ; (1, 2) ; (2, 3) ; (3, 2) ;和 (3, 1)

我需要在该多边形内生成 20 个等距的点。

注意:某些多边形可能不支持均匀分布的点,但我希望以一种尽可能一致地覆盖多边形所有区域的方式分布点。 (我的意思是我不想要一个分数比另一个多的部分)

有这样的算法吗?或者图书馆

我正在开发一个 C# 应用程序,但任何语言都可以,因为我只需要算法并且可以翻译它。

非常感谢您的帮助

【问题讨论】:

  • 您可能想尝试math.stackexchange.com 来获取算法,如果您需要帮助将算法翻译成 C#,请在此处发布。

标签: c# math polygon point


【解决方案1】:

一个简单的方法是:

  1. 计算边界框
  2. 在该框中生成点
  3. 丢弃不在感兴趣多边形中的所有点

这种方法会产生一定数量的浪费点。对于三角形,它永远不会超过 50%。对于任意多边形,它可以任意高,因此您需要查看它是否适合您。

对于任意多边形,您可以首先将多边形分解为三角形,这样您就可以保证浪费点的上限:50%。

对于等距离的点,从空间填充曲线生成点(并丢弃所有不在多边形中的点)。

【讨论】:

  • 想象一个对角线放置的非常细的矩形。这浪费了大量的样本。不过,这是一种合理的方法。
  • @romkyns,我错误地只想到了三角形。我为任意多边形添加了一个解决方案。
  • 想象一个对角线放置的细三角形... :)
  • 您可以在三角形中生成一个随机点,如下所示。每个三角形都有底和高。从 0 到高度选择两个随机数。如果第一个较小,则将第一个数字作为放置点的高度。如果第二个较小,则将(高度 - 第一个数字)作为放置点的高度。从那个高度随机选择一个点。此方法需要选择 3 个随机数。选择和丢弃直到你进入三角形平均需要 4 次,并且可能需要无限时间。
【解决方案2】:
  1. 遗传算法可以很快地做到这一点
    参考GENETIC ALGORITHMS FOR GRAPH LAYOUTS WITH GEOMETRIC CONSTRAINTS

  2. 您可以为此使用力有向图...
    http://en.wikipedia.org/wiki/Force-based_algorithms_(graph_drawing)
    它绝对会让你大吃一惊。

我没试过,
但我记得有可能为图中的某些顶点设置修复

你的算法最终会是这样的

  1. 创建图形 G = V 中顶点的闭合路径
  2. 将顶点固定到位
  3. 将 N 个顶点添加到图形中,并将它们与具有相等张力值 1.0 的边完全连接
  4. Run_force_graph(G)

将图形缩放到有界框

虽然它不会是绝对的,因为一些凸形可能会产生奇怪的结果(拿一颗星)

最后:没读过,但标题和摘要似乎相关
看看Consistent Graph Layout for Weighted Graphs

希望这会有所帮助...

【讨论】:

  • 可能是因为您提供的信息来源有助于开发答案而不是提供实际答案
【解决方案3】:

我使用的简单方法是:

  1. 对多边形进行三角剖分。剪耳是完全足够的,因为您只需将多边形分解为一组不重叠的三角形。

  2. 计算每个三角形的面积。从每个三角形中采样与该三角形相对于整体的面积成比例。每个样本只需一个统一的随机数。

  3. 一旦确定一个点来自给定的三角形,就在三角形上均匀采样。这本身比您想象的要容易。

所以实际上,这一切都归结为如何在三角形内采样。这很容易做到。一个三角形由 3 个顶点定义。我称它们为 P1、P2、P3。

  1. 选择三角形的任意一条边。生成一个沿该边缘均匀分布的点 (P4)。因此,如果 P1 和 P2 是对应端点的坐标,则如果 r 在区间 [0,1] 上均匀分布,则 P 将是沿该边缘均匀采样的点。

    P4 = (1-r)*P1 + r*P2

  2. 接下来,沿着 P3 和 P4 之间的线段进行采样,但这样做不均匀。如果 s 是区间 [0,1] 上的均匀随机数,则

    P5 = (1-sqrt(s))*P3 + sqrt(s)*P4

r 和 s 当然是独立的伪随机数。然后 P5 将被随机采样,在三角形上均匀。

好消息是它不需要拒绝方案来实现,所以长而细的多边形不是问题。而对于每个样本,成本只是需要为每个事件生成三个随机数。由于剪耳是一项相当简单且高效的任务,因此采样将是高效的,即使对于看起来很糟糕的多边形或非凸多边形也是如此。

【讨论】:

  • +1 用于对多边形进行三角剖分并对按三角形面积加权的离散分布进行采样。对于三角形内的采样,我更喜欢采样右单位三角形 [(0, 0), (0, 1), (1, 0)] 并将仿射变换应用于目标三角形;只需乘法和加法,就可以有效地预先计算和应用变换矩阵。请注意,从右侧单位三角形中采样很容易:x, y <- U; if x + y > 1, x, y := 1-y, 1-x.
  • @ecatmur - 是的,有几种方法可以在单纯形中进行采样。我使用了我选择的那个,因为对高维单纯形的扩展很容易看到。
  • 是的,但是从标准单位单纯形中采样也很容易和有效 - 参见例如stackoverflow.com/questions/3010837/…
  • 我已经设计了一个关于这个精确算法的视觉演示,如果有任何兴趣的话:cecchi.me/portfoliosource 是不必要的冗长,因为视觉组件)
【解决方案4】:

简单的答案来自一个更简单的问题:如何从均匀分布中生成给定数量的随机分布点,这些点都适合给定的多边形?

简单的答案是:找到多边形的边界框(假设它是 [a,b] x [c,d]),然后继续生成一对实数,其中一个来自 U(a,b),另一个来自 U(b,c),直到你有 n 个坐标对适合你的多边形。这很容易编程,但是,如果您的多边形非常锯齿,或者细而倾斜,则非常浪费和缓慢。

为了更好的答案,找到最小的旋转矩形边界框,并在转换后的坐标中执行上述操作。

【讨论】:

    【解决方案5】:

    更好的答案来自更好的问题。假设您要放置一组 n 个瞭望塔来覆盖一个多边形。您可以将其视为一个优化问题:找到 n 个点的 2n 个坐标,以最小化适合您目标的成本函数(或最大化价值函数)。一个可能的成本函数可以为每个点计算到其最近邻居或多边形边界的距离,以较小者为准,并计算该序列的方差作为“不均匀性”的度量。您可以使用如上获得的一组随机的 n 个点作为初始解决方案。

    我在某本书中看到过这样的“瞭望塔问题”。算法、演算或优化。

    @Youssef:抱歉耽搁了;一个朋友来了,网络中断了。

    @others:耐心点,别那么高兴。

    【讨论】:

    • 放置瞭望塔的问题并不比采样均匀分布更好;这是一个完全不同的问题。
    【解决方案6】:

    你可以使用劳埃德算法:

    https://en.m.wikipedia.org/wiki/Lloyd%27s_algorithm

    【讨论】:

      【解决方案7】:

      你可以试试 {spatialEco} 包 (https://cran.r-project.org/web/packages/spatialEco/index.html) 并应用函数 sample.poly (https://www.rdocumentation.org/packages/spatialEco/versions/1.3-2/topics/sample.poly)

      你可以试试这个代码:

      library(rgeos)
      library(spatialEco)
      
      mypoly = readWKT("POLYGON((1 1,5 1,5 5,1 5,1 1))")
      plot(mypoly)
      points = sample.poly(mypoly, n= 20, type = "regular")
      #points2 = sample.poly(mypoly, n= 20, type = "stratified")
      #another type which may answer your problem
      plot(points, col="red", add=T)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        • 2020-09-14
        • 2012-05-04
        • 1970-01-01
        • 2020-12-24
        • 1970-01-01
        相关资源
        最近更新 更多