为什么我的眼里常含泪水?因为我有一个算法不会。为了节约点眼泪,今天我们就来介绍著名的道格拉斯-普克算法,它在GIS系统中有重要应用。
道格拉斯-普克算法(Douglas–Peucker algorithm),亦称为拉默-道格拉斯-普克算法(Ramer–Douglas–Peucker algorithm),这个算法最初由拉默(Urs Ramer)于1972年提出,1973年道格拉斯(David Douglas)和普克(Thomas Peucker)二人又独立于拉默提出了该算法。我们知道,一条曲线上包含着无数个点,但是计算机在存储曲线时只能存取有限个点,通常存储的点越多,那么对该曲线的描述也就越精确。当我们要对原本用N个点描述的曲线进行压缩表示时,即采用K(K<N)个点来描述曲线,为了尽可能保证原有曲线的形态不至有太大的改变,我们就需要一种算法,而道格拉斯-普克算法就是这样一种将曲线近似表示为一系列点,并减少点的数量的一种算法。它的优点是具有平移和旋转不变性,给定曲线与阈值后,抽样结果一定。
下面,我们通过一个例子来介绍一下该算法的执行步骤。假设当前我们有一条曲线,它由8各点来描述,如下图所示
初始曲线是一系列有序的点集,我们需要设定一个距离(阈值)参数 ε > 0。最开始时,在曲线首尾两点A,B之间连接一条直线AB。算法自动将首尾两个点记下(也就是存入结果点集)。得到曲线上离该直线段(AB)距离最大的点C,计算其与AB的距离d,如下图所示
如果用直线段AB来作为原曲线的近似表示,那么点C显然是位于曲线上,离AB最远的点。现在比较距离 d 与预先给定的阈值 ε 的大小,如果小于 ε,则表明任何当前没有被记下的点都可以被丢弃了,因为用已经得到的直线段作为曲线的近似,不会比 ε 更早,即该段曲线处理完毕。
如果距离 d 大于阈值,则用C将曲线分为两段AC和BC,并将点C记下。
然后分别对已经得到两段曲线递归地进行上述处理。
↓
当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。就本例而言,接下来的处理步骤如下图所示:
↓
↓
↓
最终我们得到的(用更少的点表示的)近似曲线如下
(本文完)