Алгоритм Дугласа-Пекера — это алгоритм, позволяющий уменьшить число точек кривой, аппроксимированной большей серией точек. Алгоритм был независимо предложен Урсом Рамером в 1972 и Давидом Дугласом и Томасом Пекером в 1973. Также алгоритм известен под следующими именами: алгоритм Рамера-Дугласа-Пекера, алгоритм итеративной ближайшей точки и алгоритм разбиения и слияния.

Идея

править

Суть алгоритма состоит в том, чтобы по данной ломаной, аппроксимирующей кривую, построить ломаную с меньшим числом точек. Алгоритм определяет расхождение, которое вычисляется по максимальному расстоянию между исходной и упрощённой кривыми. Упрощенная кривая состоит из подмножества точек, которые определяются из исходной кривой.

Алгоритм

править
Анимированный пример.
Сглаживание кусочно-линейной кривой алгоритмом Дугласа-Пекера.

Начальная кривая представляет собой упорядоченный набор точек или линий, и заданное расстояние ε > 0. Начальная кривая показана на рисунке 0, упрощённая — на рисунке 4.

Алгоритм рекурсивно делит линию. Входом алгоритма служат координаты всех точек между первой и последней. Первая и последняя точка сохраняются неизменными. После чего алгоритм находит точку, наиболее удалённую от отрезка, соединяющего первую и последнюю. Если точка находится на расстоянии, меньшем ε, то все точки, которые ещё не были отмечены к сохранению, могут быть выброшены из набора и получившаяся прямая сглаживает кривую с точностью не ниже ε

Если же расстояние больше ε, то алгоритм рекурсивно вызывает себя с на наборе от начальной до данной и от данной до конечной точках (что означает, что данная точка будет отмечена к сохранению).

По окончании всех рекурсивных вызовов выходная ломаная строится только из тех точек, что были отмечены к сохранению.

Псевдокод (рекурсивная реализация)

править
function DouglasPeucker(PointList[], epsilon)
 //Находим точку с максимальным расстоянием от прямой между первой и последней точками набора
 dmax = 0
 index = 0
 for i = 2 to (length(PointList) - 1)
  d = PerpendicularDistance(PointList[i], Line(PointList[1], PointList[end])) 
  if d > dmax
   index = i
   dmax = d
  end
 end

 //Если максимальная дистанция больше, чем epsilon, то рекурсивно вызываем её на участках
 if dmax >= epsilon
  //Recursive call
  recResults1[] = DouglasPeucker(PointList[1...index], epsilon)
  recResults2[] = DouglasPeucker(PointList[index...end], epsilon)

  // Строим итоговый набор точек
  ResultList[] = {recResults1[1...end-1] recResults2[1...end]}
 else
  ResultList[] = {PointList[1], PointList[end]}
 end

 // Возвращаем результат
 return ResultList[]
end

Псевдокод (итеративная реализация)

править
function DouglasPeucker(PointList[], epsilon)
{
 // в стек заносим первый и последний индексы
 stack.push({0, length(PointList) - 1})  
 
 // в массиве по заданному индексу храним оставлять точку (true) или нет (false)
 keep_point[0...length(PointList) - 1] = true

 while(!stack.empty())
 {
   startIndex = stack.top().first
   endIndex = stack.top().second
   stack.pop()

   dMax = 0
   index = startIndex
   for(i = startIndex + 1 to endIndex - 1)
   {
      if(keep_point[i])
      {
         d = PerpendicularDistance(PointList[i], Line(PointList[startIndex], PointList[endIndex])) 
         if(d > dMax)
         {
           index = i
           dMax = d
         }
       }
    }

    if(dMax >= epsilon)
    {
       stack.push({startIndex, index})
       stack.push({index, endIndex})
    }
    else
    {
       for(j = startIndex + 1 to endIndex - 1)
       {
           keep_point[j] = false
       }
    }
 }

 for(i = 0 to (length(PointList) - 1))
 {
    if(keep_point[i])
    {
       ResultList.Add(PointList[i])
    }
 }

 return ResultList[]
}

Применение

править

Алгоритм применяется для обработки векторной графики и при картографической генерализации.

Кроме того, применяется в робототехнике[1] для обработки результатов работы кругового лазерного дальномера и поэтому также называется алгоритмом разбиения и слияния.

Сложность

править

Ожидаемая сложность алгоритма может быть оценена выражением , которая упрощается (как следствие Основной теоремы) в . Однако в худшем случае сложность алгоритма .

Примечания

править
  1. Nguyen and Martinelli and Siegwart. A Comparison of Line Extraction Algorithms using 2D Laser Rangefinder for Indoor Mobile Robotics (2005). Архивировано 17 сентября 2010 года.

Ссылки

править

📚 Artikel Terkait di Wikipedia

Метод Ньютона

// производная функции using function = double (*)(double x); // задание типа function double solve(function fx, function dfx, double x0) { double x1 =

Пуэр

oxidative stress and liver injury in rats fed a high-fat diet. Food & Function. 3 (5): 575—581. doi:10.1039/c2fo10224a. Zhang, L. (2016). Pu-erh tea extract

Python

__class__ # специальный атрибут - ссылка на класс данного объекта <type 'function'> Подавляющее большинство атрибутов, поддерживающих интроспекцию, является

ECMAScript

myObject = function() { var value = 0; return { increment: function (inc) { value += typeof inc === 'number' ? inc : 1; }, getValue: function ( ) { return

Козак, Мэрилин

translational regulation paved the way for current confusion about how microRNAs function. Gene. 423 (2): 108—15. doi:10.1016/j.gene.2008.07.013. PMID 18692553.

Ишемическая болезнь сердца

M Ferrari, S Betge. Collateral function in chronic total coronary occlusions is related to regional myocardial function and duration of occlusion // Circulation

Мастурбация

Baker & Bellis, 1993, p. 23. Thomsen, Ruth. Sperm Competition and the Function of Masturbation in Japanese Macaques (Macaca fuscata) : Dissertation :

Кошка

оригинала 4 мая 2012 года. Patricia Smith, Eitan Tchernov. Structure, function and evolution of teeth (англ.). — Freund Publishing House Ltd., 1992. —