Algorithm Visvalingam-Whyatt多段线简化算法

Algorithm Visvalingam-Whyatt多段线简化算法,algorithm,polyline,simplification,Algorithm,Polyline,Simplification,我正在尝试实现一个多段线简化算法。可以在此处找到原始文章:。这在概念上似乎很简单,但我不理解提供的示例算法(我认为它的措辞很糟糕),我希望有人能提供一些见解。从这篇文章中,我得出的基本观点是 计算每个点的有效面积(由直线上三个连续点之间的三角形形成),并删除面积为0的点 从最小区域开始,将点的区域与阈值进行比较,如果该区域低于该阈值,则将其从多段线中删除 移动到两个相邻的点,并在它们发生更改时重新计算它们的面积 返回到2,直到删除阈值下的所有点区域 算法如下(逐字复制自文章): 计算每个点的有

我正在尝试实现一个多段线简化算法。可以在此处找到原始文章:。这在概念上似乎很简单,但我不理解提供的示例算法(我认为它的措辞很糟糕),我希望有人能提供一些见解。从这篇文章中,我得出的基本观点是

  • 计算每个点的有效面积(由直线上三个连续点之间的三角形形成),并删除面积为0的点
  • 从最小区域开始,将点的区域与阈值进行比较,如果该区域低于该阈值,则将其从多段线中删除
  • 移动到两个相邻的点,并在它们发生更改时重新计算它们的面积
  • 返回到2,直到删除阈值下的所有点区域
  • 算法如下(逐字复制自文章):

    • 计算每个点的有效面积 删除所有面积为零的点,并将其存储在此区域的单独列表中
    • 重复
      • 找到有效面积最小的点,称之为当前点。如果其计算面积小于要消除的最后一个点的面积,则使用后者的面积。(这可确保在不消除以前消除的点的情况下,无法消除当前点。)
      • 从原始列表中删除当前点,并将其与其关联区域一起添加到新列表中,以便在运行时过滤该线
      • 重新计算两个相邻点的有效面积(见图1b)
    • 直到
      • 原始直线仅由两个点组成,即起点和终点

    我对第一步“REPEAT”下的“if”子句感到困惑。。。有人能澄清一下吗?

    该算法的本质是按重要性对点进行排序。该点的重要性由其有效面积近似表示

    假设已删除点A,然后重新计算点B的有效面积。新面积可以大于或小于旧面积。它可以小于A的有效面积。但是,该算法仍然认为B比A更重要


    if
    子句的目的是确保最终列表中的B点比A点更重要,仅此而已。

    FWIW.js的创建者Mike Bostock为该算法编写了一个紧凑的javascript实现(Visvalingam的算法)


    我也被这一点弄糊涂了,回去再看一遍这篇文章,如果你在移动点的时候就不需要了——也就是说,如果你用固定的区域阈值进行一次性简化。afaict javascript实现就是这样工作的,因此它实际上不需要“if”语句(但无论如何,它都有它)


    如果你要保留所有要点,就需要“如果”语句。在这种情况下,您将存储每个点的“有效面积”,以便以后可以过滤它们,也许可以使用一个交互式滑块来控制输出点的大小。通过存储更大的有效区域,您可以保持适当的顺序。

    为什么这听起来像是《生活大爆炸理论》一集的标题?因为您看了太多电视:)哈哈,实际上col(咯咯笑)文章链接对我来说很好。也许这是一个间歇的问题。为便于参考,本文标题为©Visvalingam,M.和Whyatt,J.D.(1992年)通过重复消除最小面积进行的线概括,这是有意义的。通过使B比A更重要,可以确保在最后按正确的顺序过滤掉点。这段代码中的三角形区域计算有一个错误,它应该是:
    函数区域(t){return Math.abs((t[0][0]-t[1][0])*(t[2][1]-t[1][1]-(t[0][0]-t[1][0])*(t[2][1]-t[1]);
    。这会导致错误地简化海岸线(显示的结果比您可能得到的结果更糟糕)。此外,最大面积节省在这个实现中是无用的,因为它是迭代的。建议的表达式是常数零,因为它从自身子结构
    (t[0][0]-t[1][0])*(t[2][1]-t[1][1])