<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Muravyov</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Muravyov"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Muravyov"/>
		<updated>2026-06-11T16:46:35Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=25020</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=25020"/>
				<updated>2012-06-11T18:32:19Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Оценка работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px|thumb|right]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24991</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24991"/>
				<updated>2012-06-11T17:28:45Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Корректность */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px|thumb|right]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24990</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24990"/>
				<updated>2012-06-11T17:27:17Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px|thumb|right]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24989</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24989"/>
				<updated>2012-06-11T17:26:32Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px|right]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24987</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24987"/>
				<updated>2012-06-11T17:25:59Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px|rigth]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24985</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24985"/>
				<updated>2012-06-11T17:24:16Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24984</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24984"/>
				<updated>2012-06-11T17:22:02Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): // определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24983</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24983"/>
				<updated>2012-06-11T17:20:26Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим горизонтальную заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24981</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24981"/>
				<updated>2012-06-11T17:16:09Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Основные понятия */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, если в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24980</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24980"/>
				<updated>2012-06-11T17:13:14Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Оценкка работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
# '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
# '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log n)&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log n)&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24978</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24978"/>
				<updated>2012-06-11T17:09:56Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Основные понятия */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по координате &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24950</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24950"/>
				<updated>2012-06-11T14:12:23Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Корректность */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. Существование ушей в свою очередь следует из теоремы, доказанной выше. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24949</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24949"/>
				<updated>2012-06-11T14:09:33Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
Пример работы алгоритма (нумерация вершин задаёт порядок обхода): &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Big example ear.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Big_example_ear.jpg&amp;diff=24947</id>
		<title>Файл:Big example ear.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Big_example_ear.jpg&amp;diff=24947"/>
				<updated>2012-06-11T14:04:16Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24936</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24936"/>
				<updated>2012-06-11T12:56:41Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.&lt;br /&gt;
[[Файл:Ear_case2.jpg|400px|thumb|center|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; не является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Желтым и зелёным отмечены уши, принадлежащие &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; соответственно.]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear_case2.jpg&amp;diff=24935</id>
		<title>Файл:Ear case2.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear_case2.jpg&amp;diff=24935"/>
				<updated>2012-06-11T12:53:00Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24927</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24927"/>
				<updated>2012-06-11T11:58:46Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
[[Файл:Ear case1.jpg‎|300px|thumb|left|Случай, когда &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear_case1.jpg&amp;diff=24926</id>
		<title>Файл:Ear case1.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear_case1.jpg&amp;diff=24926"/>
				<updated>2012-06-11T11:40:54Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24917</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24917"/>
				<updated>2012-06-11T11:23:22Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:4vertex 2ear.jpg‎|200px|thumb|right|Тривиальный пример многоугольника с четырьмя вершинами. &amp;lt;tex&amp;gt;E_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E_2&amp;lt;/tex&amp;gt; — уши]]&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:4vertex_2ear.jpg&amp;diff=24916</id>
		<title>Файл:4vertex 2ear.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:4vertex_2ear.jpg&amp;diff=24916"/>
				<updated>2012-06-11T11:16:37Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24915</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24915"/>
				<updated>2012-06-11T10:58:18Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=&lt;br /&gt;
Доказательство будем вести по индукции. Базовый случай: &amp;lt;tex&amp;gt;n = 4&amp;lt;/tex&amp;gt; &amp;lt;здесь должна быть пикча&amp;gt;. Предположим для всех многоугольников, количество вершин в которых не больше &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, теорема верна. Рассмотрим многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в котором &amp;lt;tex&amp;gt;n+1&amp;lt;/tex&amp;gt; вершина. Далее возможны два случая:&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является ухом. Отрезав это ухо, мы уменьшим число вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на одну. В результате, получиv &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинный многоугольник &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt;. По предположению индукции у него существует два непересекающихся уха. Учитывая, что уши &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; являются ушами и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, несложно заметить, что для &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теорема верна.&lt;br /&gt;
&lt;br /&gt;
* Произвольная вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не является ухом. В таком случае в треугольнике &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; лежат вершины, принадлежащие &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Из этих вершин выберем вершину &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, которая будет ближе всего к &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Проведём отрезок &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;, который разделит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника: &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. В каждом из них будет не более &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершин, следовательно у каждого будет по два непересекающихся уха. Даже если предположить, что ухо из &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и ухо из &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; будут пересекаться по стороне &amp;lt;tex&amp;gt;v_{i}q&amp;lt;/tex&amp;gt;, в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всё равно будет не менее двух непересекающихся ушей.}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода. &lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24911</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=24911"/>
				<updated>2012-06-11T09:47:37Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде списка &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения &lt;br /&gt;
                                                              //диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last &amp;lt;tex&amp;gt;\leftarrow&amp;lt;/tex&amp;gt; S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагонали от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
[[Файл:Ear1.jpg‎|350px|thumb|left|В первом случае выделенная вершина является ухом, в остальных нет]]&lt;br /&gt;
&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании двух ушей многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует два не пересекающихся между собой уха.&lt;br /&gt;
|proof=}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, и где возможно, будем отрезать уши до тех пор, пока &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не станет треугольником.&lt;br /&gt;
&lt;br /&gt;
Будем рассматривать вершины многоугольника в порядке обхода. Индексирование вершин для удобства будем вести по модулю &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;, т.е. &amp;lt;tex&amp;gt;v_{-1} = v_{n-1}&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_0 = v_n&amp;lt;/tex&amp;gt;. Если вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; является ухом, построим диагональ &amp;lt;tex&amp;gt;v_{i+1}v_{i-1}&amp;lt;/tex&amp;gt; и отрежем треугольник &amp;lt;tex&amp;gt;\Delta v_{i-1}v_{i}v_{i+1}&amp;lt;/tex&amp;gt; от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В противном случае переходим к следующей вершине &amp;lt;tex&amp;gt;v_{i+1}&amp;lt;/tex&amp;gt; в порядке обхода.&lt;br /&gt;
&lt;br /&gt;
==== Алгоритм ====&lt;br /&gt;
При проверке каждой вершину следует для начала проверить, является ли она выпуклой, в противном случае её просто нет надобности рассматривать в качестве уха. Это несложно сделать, воспользовавшись [[Предикат_&amp;quot;левый_поворот&amp;quot;|левым поворотом]]. &amp;quot;Ушную&amp;quot; проверку вершины будем осуществлять алгоритмом принадлежности точки &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнику (в нашем случае треугольнику). В качестве поддерживаемых структур удобно хранить DCEL, в котором будем строить новые диагонали, и список вершин с двойными связями, аналогичный DCEL по построению.&lt;br /&gt;
&lt;br /&gt;
==== Псевдокод ====&lt;br /&gt;
 DCVL D1 //список вершин doubly connected vertex list по аналогии с DCEL&lt;br /&gt;
 DCEL D2&lt;br /&gt;
 Construct(D1);&lt;br /&gt;
 Construct(D2);&lt;br /&gt;
 vertex v = random_vertex_of(D1);&lt;br /&gt;
 while size_of(D1) &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; 3&lt;br /&gt;
    if IsConvex(v)  //проверка на выпуклость&lt;br /&gt;
       for each Vertex v_i in D1&lt;br /&gt;
          if v_i &amp;lt;tex&amp;gt; \neq &amp;lt;/tex&amp;gt; v, v.prev(), v.next()                 //проверка всех вершин на &lt;br /&gt;
                and v_i &amp;lt;tex&amp;gt;\in &amp;lt;/tex&amp;gt; Triangle(v, v.prev(), v.next())//принадлежность треугольнику, &lt;br /&gt;
                                                         //одной из вершин которого&lt;br /&gt;
                                                         //является потенциальное ухо v.&lt;br /&gt;
             edge e = new edge(v.prev, v.next)&lt;br /&gt;
             Insert e in D2;&lt;br /&gt;
             v = v.next&lt;br /&gt;
             Delete v.prev from D1&lt;br /&gt;
&lt;br /&gt;
==== Корректность ====&lt;br /&gt;
При нахождении каждого уха от многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезается треугольник, состоящий из самого уха и его двух смежных вершин. В конце алгоритма, когда все уши от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; отрезаны, остается только один треугольник. Как несложно видеть, триангуляция выстраивается корректно.&lt;br /&gt;
&lt;br /&gt;
==== Оценка работы ====&lt;br /&gt;
Изначально в многоугольнике содержится &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; ушей. Нетрудно понять, что в процессе отрезания ушей, смежные точки могут тоже становиться ушами. В результате триангуляции образуется &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагонали, соответственно максимальное количество вершин, которые в процессе могут становиться ушами &amp;lt;tex&amp;gt;2n - 6&amp;lt;/tex&amp;gt;. Итого общее количество ушей будет &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Определить, является ли вершина ухом можно за &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, поскольку используется алгоритм определения принадлежности точки треугольнику — это &amp;lt;tex&amp;gt;\mathcal{O}(3)&amp;lt;/tex&amp;gt;. Таким образом общий процесс отрезания ушей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Невыпуклых вершин всего &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, каждая из них обрабатывается за константу, поэтому общее время для их обработки &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. Списки рёбер и вершин строятся за линейное время, добавление ребра и удаление вершины в каждом из них работает за константу. Общее время &amp;lt;tex&amp;gt;\mathcal{O}(n^2)&amp;lt;/tex&amp;gt;. Поскольку храним только два списка — память линейная.&lt;br /&gt;
&lt;br /&gt;
ДОПИЛЮ ЕЩЁ.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;br /&gt;
&lt;br /&gt;
* [http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/cutting_ears.html  Ear Cutting for Simple Polygons]&lt;br /&gt;
&lt;br /&gt;
* [http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf  Triangulation by ear-clipping]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear1.jpg&amp;diff=24910</id>
		<title>Файл:Ear1.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear1.jpg&amp;diff=24910"/>
				<updated>2012-06-11T09:46:12Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: загружена новая версия «Файл:Ear1.jpg»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear1.jpg&amp;diff=24908</id>
		<title>Файл:Ear1.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Ear1.jpg&amp;diff=24908"/>
				<updated>2012-06-11T09:39:19Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22233</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22233"/>
				<updated>2012-05-12T16:39:40Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; называется '''ухом''', если диагональ &amp;lt;tex&amp;gt;v_{i-1}v_{i+1}&amp;lt;/tex&amp;gt; лежит строго во внутренней области многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Идея ====&lt;br /&gt;
Рассмотрим все вершины многоугольника, и где возможно, будем отрезать уши.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22167</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22167"/>
				<updated>2012-05-09T15:07:29Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Примитивный алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней области многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
// ещё допишу.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22115</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22115"/>
				<updated>2012-05-09T07:17:34Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
// ещё допишу.&lt;br /&gt;
&lt;br /&gt;
== Источники ==&lt;br /&gt;
* Mark de Berg, Marc van Kreveld, Mark Overmars, and Otfried Schwarzkopf (2000), Computational Geometry (2nd revised ed.), Springer-Verlag, ISBN 3-540-65620-0 Chapter 3: Polygon Triangulation: pp.45–61.&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22101</id>
		<title>Триангуляция полигонов (ушная + монотонная)</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D1%80%D0%B8%D0%B0%D0%BD%D0%B3%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F_%D0%BF%D0%BE%D0%BB%D0%B8%D0%B3%D0%BE%D0%BD%D0%BE%D0%B2_(%D1%83%D1%88%D0%BD%D0%B0%D1%8F_%2B_%D0%BC%D0%BE%D0%BD%D0%BE%D1%82%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F)&amp;diff=22101"/>
				<updated>2012-05-08T19:45:42Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: Новая страница: «'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треуголь...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
// ещё допишу.&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%B3%D0%B5%D0%BE%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%8F&amp;diff=22100</id>
		<title>Вычислительная геометрия</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%B3%D0%B5%D0%BE%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%8F&amp;diff=22100"/>
				<updated>2012-05-08T19:45:10Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория: Вычислительная геометрия]]&lt;br /&gt;
* [[Представление чисел с плавающей точкой]]&lt;br /&gt;
* [[Предикат &amp;quot;левый поворот&amp;quot;]]&lt;br /&gt;
* [[Интервальная арифметика]]&lt;br /&gt;
* [[Adaptive precision arithmetic]]&lt;br /&gt;
* [[Алгоритм Бентли-Оттмана]]&lt;br /&gt;
* [[Конфигурация]]&lt;br /&gt;
* [[Трапецоидная карта]]&lt;br /&gt;
* [[Пересечение окружностей]]&lt;br /&gt;
* [[Упрощение полигональной цепи]]&lt;br /&gt;
* [[Ортогональный поиск]]&lt;br /&gt;
* [[Алгоритмы построения выпуклых оболочек множества точек на плоскости]]&lt;br /&gt;
* [[Триангуляция полигонов (ушная + монотонная)]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* [[Список тем]]&lt;br /&gt;
* [[Обсуждение:Вычислительная геометрия#Сдача конспектов | Сдача конспектов]]&lt;br /&gt;
* [[Обсуждение:Вычислительная геометрия#Презентации | Сдача презентаций]]&lt;br /&gt;
* [[Обсуждение:Вычислительная геометрия#Условия и чекеры | Условия и чекеры]]&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22098</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22098"/>
				<updated>2012-05-08T19:43:49Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Ушной метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
// ещё допишу.&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22097</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22097"/>
				<updated>2012-05-08T19:43:07Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Прочие случаи */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
[[Файл:Monotone with holes.png|350px|thumb|right|Пример отверстия в форме монотонного многоугольника. У него обязательно будут существовать start и end вершина, если рассматривать его как обычный многоугольник. Однако, когда он станет полигональным отверстием, в силу определения start и end вершины обратятся в split и merge, которые соединятся с какими-то вершинами внешнего контура]]&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Monotone_with_holes.png&amp;diff=22091</id>
		<title>Файл:Monotone with holes.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Monotone_with_holes.png&amp;diff=22091"/>
				<updated>2012-05-08T19:37:24Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22089</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22089"/>
				<updated>2012-05-08T19:10:36Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки]]&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22088</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22088"/>
				<updated>2012-05-08T19:09:53Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
[[Файл:Triang alg case2.jpg|500px|thumb|center|Второй случай. Синим помечена цепь из вершин, которая содержится в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на момент достижения вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;]], рыжей помечена первая вершина, до которой невозможно провести диагональ, жёлтой помечена новая нетриангулированная область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в форме воронки.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triang_alg_case2.jpg&amp;diff=22086</id>
		<title>Файл:Triang alg case2.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triang_alg_case2.jpg&amp;diff=22086"/>
				<updated>2012-05-08T19:02:55Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22084</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22084"/>
				<updated>2012-05-08T18:46:39Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Триангуляция монотонного многоугольника */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22083</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22083"/>
				<updated>2012-05-08T18:44:48Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Алгоритм */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
[[Файл:Triang_alg_case1.jpg|200px|thumb|right|Первый случай. Синим помечены стороны воронки, зелёным — диагонали, а жёлтым границы новой ещё не протриангулированной области]]&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triang_alg_case1.jpg&amp;diff=22082</id>
		<title>Файл:Triang alg case1.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triang_alg_case1.jpg&amp;diff=22082"/>
				<updated>2012-05-08T18:39:28Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22081</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22081"/>
				<updated>2012-05-08T18:32:36Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Идея */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
[[Файл:Triangulationg intro.jpg|170px|thumb|right|Зелёным помечена так называемая воронка, которая образуется, когда мы достигнем красной вершины]]&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triangulationg_intro.jpg&amp;diff=22080</id>
		<title>Файл:Triangulationg intro.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Triangulationg_intro.jpg&amp;diff=22080"/>
				<updated>2012-05-08T18:28:19Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22073</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22073"/>
				<updated>2012-05-08T16:36:28Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке. [[Файл:2_examples_of_tringl.jpg‎|300px|thumb|right|Два способа триангуляции одной и той же фигуры]]&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:2_examples_of_tringl.jpg&amp;diff=22072</id>
		<title>Файл:2 examples of tringl.jpg</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:2_examples_of_tringl.jpg&amp;diff=22072"/>
				<updated>2012-05-08T16:34:00Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22071</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22071"/>
				<updated>2012-05-08T16:19:21Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Монотонный метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
==== Прочие случаи ====&lt;br /&gt;
Алгоритм так же работает и для частных случаев, например для многоугольника с полигональным отверстием. Такой многоугольник будет поделен на части без отверстий и будет успешно триангулирован. Это обуславливается тем, что хотя бы две вершины, принадлежащих отверстию будут split и merge (см. рисунок). Диагональ от таких вершин можно провести только до вершин внешнего контура, а поскольку у внутреннего отверстия хотя бы одна split и одна merge вершина весь многоугольник будет разделён как минимум на две части.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22070</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22070"/>
				<updated>2012-05-08T16:00:39Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Монотонный метод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Общая оценка ====&lt;br /&gt;
Разбиение многоугольника на монотонные части занимает &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; памяти. Триангуляция каждой из частей занимает линейную память и время. Учитывая то, что суммарное количество вершин во всех частях &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;, триангуляция всех частей займёт &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по времени и по памяти.&lt;br /&gt;
&lt;br /&gt;
В итоге общая оценка составляет &amp;lt;tex&amp;gt;\mathcal{O}(n \log n)&amp;lt;/tex&amp;gt; по времени и &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; по памяти.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22069</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22069"/>
				<updated>2012-05-08T15:50:20Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Корректность */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22068</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22068"/>
				<updated>2012-05-08T15:49:38Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Триангуляция монотонного многоугольника */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
Данный алгоритм корректен, поскольку:&lt;br /&gt;
* Все построенные диагонали попарно не пересекаются. Это гарантируется тем, что при каждом просмотре определённой вершины рассматривается только та часть &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, которая не была протриангулирована, следовательно внутри этой области по определению не может лежать ни одной из уже построенных диагоналей. Несложно заметить, что в стеке &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt; на каждой итерации главного цикла хранятся вершины, которые принадлежат именно &amp;lt;tex&amp;gt;P'&amp;lt;/tex&amp;gt; и лежат выше рассматриваемой вершины.&lt;br /&gt;
* Количество построенных диагоналей всегда будет &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt;, поэтому непротриангулированных частей в многоугольнике не останется.&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22066</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22066"/>
				<updated>2012-05-08T15:17:38Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Оценка работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин требует линейное время и занимает линейную память. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22065</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22065"/>
				<updated>2012-05-08T15:14:27Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Оценка работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин занимает линейное время. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, ограничено &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22064</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22064"/>
				<updated>2012-05-08T15:13:46Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Оценка работы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
Построение массива вершин занимает линейное время. Главный цикл ''for'' выполняется &amp;lt;tex&amp;gt;n-3&amp;lt;/tex&amp;gt; раза. Каждая его итерация может потребовать линейное время. Однако заметим, что на каждой итерации главного цикла в стек кладутся максимум две вершины, следовательно общее число выполнения операции ''push'', включая первые две вершины, положенные в начале алгоритма, — &amp;lt;tex&amp;gt;2n-4&amp;lt;/tex&amp;gt;. Количество операций ''pop'' за время работы алгоритма не превысит количества операций ''push''. Отсюда общее время работы цикла ''for'' &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;. В итоге общее время работы &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22058</id>
		<title>Участник:Muravyov</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Muravyov&amp;diff=22058"/>
				<updated>2012-05-08T14:06:42Z</updated>
		
		<summary type="html">&lt;p&gt;Muravyov: /* Псевдокод */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Триангуляция полигона '''  —  декомпозиция многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на множество треугольников, внутренние области которых попарно не пересекаются и объединение которых в совокупности составляет &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. В строгом смысле слова, вершины этих треугольников должны совпадать с вершинами исходного многоугольника. Триангуляция любого многоугольника не единственна. В этом можно убедиться из примера на рисунке.&lt;br /&gt;
&lt;br /&gt;
== Постановка задачи ==&lt;br /&gt;
&lt;br /&gt;
На плоскости задан произвольный многоугольник. Стороны многоугольника не пересекаются. Требуется найти его триангуляцию.&lt;br /&gt;
&lt;br /&gt;
== Теорема о существовании трингуляции ==&lt;br /&gt;
&lt;br /&gt;
'''Простым многоугольником''' является фигура, ограниченная одной замкнутой ломаной, стороны которой не пересекаются. Таким образом, случаи многоугольников с дырками в теореме исключаются.&lt;br /&gt;
{{Теорема&lt;br /&gt;
|about = О существовании триангуляции многоугольника&lt;br /&gt;
|statement =&lt;br /&gt;
У любого простого &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-вершинного многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; всегда существует триангуляция, причём количество треугольников в ней &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; независимо от самой триангуляции.&lt;br /&gt;
|proof=&lt;br /&gt;
[[Файл:Proof theorem.jpg|200px|thumb|right|Два случая в доказательстве теоремы]]&lt;br /&gt;
Доказательство ведётся индуктивно по &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;n = 3&amp;lt;/tex&amp;gt; теорема тривиальна. Рассмотрим случай при &amp;lt;tex&amp;gt;n &amp;gt; 3&amp;lt;/tex&amp;gt; и предположим, что теорема выполняется при всех &amp;lt;tex&amp;gt;m &amp;lt; n&amp;lt;/tex&amp;gt;. Докажем существование диагонали в многоугольнике &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Возьмём самую левую по оси &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и две смежных с ней вершины &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;w&amp;lt;/tex&amp;gt;. Если отрезок  &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; принадлежит внутренней области &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; — мы нашли диагональ. В противном случае, во внутренней области треугольника &amp;lt;tex&amp;gt;\Delta uwv&amp;lt;/tex&amp;gt; или на самом отрезке &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; содержится одна или несколько вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Выберем самую наиболее далеко отстоящую от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt; вершину &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Отрезок, соединяющий &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt; не может пересекать сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, поскольку в противном случае одна из вершин это отрезка будет располагаться дальше от &amp;lt;tex&amp;gt;uw&amp;lt;/tex&amp;gt;, чем &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. Это противоречит условию выбора &amp;lt;tex&amp;gt;v'&amp;lt;/tex&amp;gt;. В итоге получаем, что &amp;lt;tex&amp;gt;v'v&amp;lt;/tex&amp;gt; — диагональ. &lt;br /&gt;
Любая диагональ делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;. За &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; обозначим количество вершин в &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; соответственно. &amp;lt;tex&amp;gt;m_1 &amp;lt; n&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2 &amp;lt; n&amp;lt;/tex&amp;gt;, поэтому по предположению индукции у &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt; существует триангуляция, следовательно и у &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; она существует.&lt;br /&gt;
&lt;br /&gt;
Докажем, что триангуляция &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;n - 2&amp;lt;/tex&amp;gt; треугольников. Рассмотрим произвольную диагональ &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; в триангуляции &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt; делит &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на два многоугольника &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, количество вершин в которых  &amp;lt;tex&amp;gt;m_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;m_2&amp;lt;/tex&amp;gt; соответственно. Каждая вершина &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; встречается только в одном из двух многоугольников &amp;lt;tex&amp;gt;P_1&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P_2&amp;lt;/tex&amp;gt;, за исключением тех, которые являются концами &amp;lt;tex&amp;gt;d&amp;lt;/tex&amp;gt;, поэтому справедливо следующее: &amp;lt;tex&amp;gt;m_1 + m_2 = n + 2&amp;lt;/tex&amp;gt;. По индукции, любая триангуляция &amp;lt;tex&amp;gt;P_i&amp;lt;/tex&amp;gt; состоит из &amp;lt;tex&amp;gt;m_i - 2&amp;lt;/tex&amp;gt; треугольников, откуда следует, что &amp;lt;tex&amp;gt;T_P&amp;lt;/tex&amp;gt;. состоит из &amp;lt;tex&amp;gt;(m_1 - 2) + (m_2 - 2) = n - 2&amp;lt;/tex&amp;gt; треугольников.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Способы нахождения триангуляции ==&lt;br /&gt;
=== Примитивный алгоритм ===&lt;br /&gt;
В общем случае в произвольном &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-угольнике всего &amp;lt;tex&amp;gt;n^2&amp;lt;/tex&amp;gt; возможных вариантов построения диагоналей. За &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt; проверим каждый из них. Для этого выясним:&lt;br /&gt;
* пересекает ли данная диагональ многоугольник  —  находится за линейное время проверкой по всем рёбрам&lt;br /&gt;
* принадлежит ли диагональ внутренней область многоугольника.&lt;br /&gt;
Чтобы построить триангуляцию нужно найти &amp;lt;tex&amp;gt;n - 3&amp;lt;/tex&amp;gt; диагоналей. В результате получается оценка &amp;lt;tex&amp;gt;\mathcal{O}(n^4)&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Для некоторых классов многоугольников предыдущую оценку можно улучшить. Например, если многоугольник выпуклый, то достаточно лишь выбирать одну его вершину и соединять со всеми остальными, кроме его соседей. В итоге оценка &amp;lt;tex&amp;gt;\mathcal{O}(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Монотонный метод ===&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Простой многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; называется '''монотонным''' относительно прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, если любая &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt;, такая что &amp;lt;tex&amp;gt;l' \perp l&amp;lt;/tex&amp;gt;, пересекает стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не более двух раз (результатом пересечения &amp;lt;tex&amp;gt;l'&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; может быть только один отрезок или точка).&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Многоугольник, монотонный относительно &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси называется '''&amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным'''.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Суть данного метода заключается в том, чтобы разбить многоугольник на монотонные части, а затем триангулировать каждую из них.&lt;br /&gt;
==== Разбиение многоугольника на монотонные части ====&lt;br /&gt;
===== Основные понятия =====&lt;br /&gt;
[[Файл:Split-merge.png|500px|thumb||Пять типов вершин]]&lt;br /&gt;
&lt;br /&gt;
Рассмотрим самую верхнюю — максимальную по оси &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершину. Будем идти вниз по рёбрам до самой нижней — соотвественно минимальной по &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt; вершине, то есть таким образом, что для некоторой вершины &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;y_j &amp;gt; y_{j+1}&amp;lt;/tex&amp;gt;. '''Поворотной''' назовём вершину &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;, на которой направление обхода будет меняется: &amp;lt;tex&amp;gt;y_{i-1} &amp;gt; y_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;y_i &amp;lt; y_{i+1}&amp;lt;/tex&amp;gt;. Опишем более подробно этот тип вершин. &lt;br /&gt;
Уточним понятния ''выше'' и ''ниже'': точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''ниже'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y &amp;lt; q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;gt; q_x&amp;lt;/tex&amp;gt;, соответственно точка &amp;lt;tex&amp;gt;p&amp;lt;/tex&amp;gt; лежит ''выше'' точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;, если &amp;lt;tex&amp;gt;p_y &amp;gt; q_y&amp;lt;/tex&amp;gt; или если &amp;lt;tex&amp;gt;p_y = q_y&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;p_x &amp;lt; q_x&amp;lt;/tex&amp;gt;. Это было сделано для того, чтобы избежать неопределённых ситуаций с вершинами, у которых &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты равны.&lt;br /&gt;
&lt;br /&gt;
Обозначим за &amp;lt;tex&amp;gt;\phi&amp;lt;/tex&amp;gt; внутренний угол при некоторой вершине вершине и определим далее пять типов вершин, четыре из которых являются поворотными:&lt;br /&gt;
* '''''start вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''split вершина''''' — два её соседа лежат ниже её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''end вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;lt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''merge вершина''''' — два её соседа лежат выше её самой и &amp;lt;tex&amp;gt; \phi &amp;gt; \pi &amp;lt;/tex&amp;gt;&lt;br /&gt;
* '''''regular вершина''''' — не является поворотной, в отличие от остальных, другими словами один её сосед находится выше, а другой ниже её самой.&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; является &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, когда в нём отсутствуют split и merge вершины.&lt;br /&gt;
|proof=&lt;br /&gt;
Предположим, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный. Тогда докажем, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; содержит split и merge вершины. Поскольку &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонный, горизонтальная прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает его стороны более двух раз. Выберем &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; таким образом, чтобы самой левой компонентой пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; был бы отрезок &amp;lt;tex&amp;gt;pq&amp;lt;/tex&amp;gt;. Далее будем двигаться наверх по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, начиная от точки &amp;lt;tex&amp;gt;q&amp;lt;/tex&amp;gt;. В результате в некоторой точке &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;r \neq p&amp;lt;/tex&amp;gt; (случай '''(a)''' на рисунке), прямая &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; снова пересечёт одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Отсюда самая высокая точка, которую мы достигли во время движения по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, будет split вершиной.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Proof_lemma.jpg|450px]]&lt;br /&gt;
&lt;br /&gt;
Если же &amp;lt;tex&amp;gt;r = p&amp;lt;/tex&amp;gt; (случай '''(b)''' на рисунке), начём опять двигаться по сторонам &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; теперь уже вниз. Как и в предыдущем случае найдётся некоторая точка &amp;lt;tex&amp;gt;r'&amp;lt;/tex&amp;gt;, которая будет результатом пересечения &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. При этом &amp;lt;tex&amp;gt;r' \neq p&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; будет пересекать &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; только два раза, то есть &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-монотонным, что противоречит нашему предположению. Аналогично предыдущему случаю, выберем теперь самую низкую точку, которую мы достигли во время движения по сторонам P. Она будет merge вершиной.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Чтобы сделать многоугольник монотонным, нужно избавиться от split и merge вершин путём проведения непересекающихся дигоналей из таких вершин.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим заметающую прямую &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, перпендукулярную &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-оси, будем перемещать её сверху вниз вдоль плоскости на которой лежит исходный многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Будем останавливать её в каждой вершине многоугольника. В тот момент, когда на пути заметающей прямой встречается split или merge вершина её нужно соединить с вершиной, у которой расстояние до &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; минимально, при этом она должна лежать соответственно выше или ниже &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;.&lt;br /&gt;
[[Файл:Split_case.jpg|200px|thumb|right|Обработка ''split'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;]] Рассмотрим каждый случай подробнее:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1) '''''Split вершина'''''. Пусть &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; — ближайшее левое и правое ребро относительно split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, которые &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент. Нам нужно найти вершину, лежащую между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;, наиболее приближённую к &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, либо если такой точки не существет выбрать минимальную из верхних вершин &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt;. Для этого будем хранить указатель на искомую вершину у левого ребра &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt;, который можно заранее вычислить. Тип вершины, хранящийся в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; не имеет значения. Таким образом, чтобы построить диагональ для split вершины нужно обратиться к указателю &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; её левого ребра, которое &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; пересекает в данный момент.&lt;br /&gt;
&lt;br /&gt;
2) '''''Merge вершина'''''. В отличие от случая со split вершиной заранее вычислить указатель &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; нельзя, поскольку merge вершина &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; должна быть соединена с вершиной, лежащей ниже заметающей прямой &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;. Для этого в &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt; левого относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; ребра запишем саму &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Далее спускаем заметающую прямую вниз к следующей вершине &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, обращаемся к &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'у её левого ребра. Проверяем, если там хранится merge вершина, строим диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt;. Последняя проверка осуществляется для любого типа вершины, кроме split, согласно п.1.&lt;br /&gt;
[[Файл:Merge_case_1_2.jpg|500px|thumb|center|Обработка ''megre'' вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. На рисунке слева &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; записывается в качестве &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;'а своего левого ребра. На правом рисунке ближайшая вершина &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt; при обращении к своему левому ребру &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; находит &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и образует диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
===== Структуры данных =====&lt;br /&gt;
В подходе, описанном выше, требуется находить пересечения заметающей прямой и левых ребёр многоугольника. Создадим двоичное дерево поиска &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, в листьях которого будем хранить рёбра, пересекающие &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt;, такие, что внутренняя область многоугольника будет лежать справа от них самих. С каждым таким ребром будем хранить его &amp;lt;tex&amp;gt;helper&amp;lt;/tex&amp;gt;. Порядок следования листьев в дереве  соответствует порядку следования рёбер в многоугольнике: слева направо. Дерево изменяется в зависимости от текущего состояния заметающей прямой. Создадим приоритетную очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; из вершин, в которой приоритетом будет &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координата вершины. Если две вершины имеют одинаковые &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты, больший приоритет у левой. Вершины будут добавляться на &amp;quot;остановках&amp;quot; заметающей прямой.&lt;br /&gt;
&lt;br /&gt;
Многоугольник &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; и добавленные в процессе диагонали удобно хранить в виде спика &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; рёбер с двойными связями (''DCEL — doubly-connected edge list''), так как потом это обеспечит эффективный доступ к каждой из частей, которые нужно будет триангулировать.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
 MakeMonotone(P)&lt;br /&gt;
    Construct(D);&lt;br /&gt;
    Construct(Q); // функция Construct создаёт объекты &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; , описанные выше.&lt;br /&gt;
    bst T = new bst();&lt;br /&gt;
    while  Q &amp;lt;tex&amp;gt; \neq  \varnothing &amp;lt;/tex&amp;gt;&lt;br /&gt;
       Remove &amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt; from Q // удаление вершины с наивысшим приоритетом из &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt;    &lt;br /&gt;
       switch (Type_of_vertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;)): //определение типа вершины&lt;br /&gt;
          case 'start':&lt;br /&gt;
             HandleStartVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'end':&lt;br /&gt;
             HandleEndVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'split':&lt;br /&gt;
             HandleSplitVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'merge':&lt;br /&gt;
             HandleMergeVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
          case 'regular':&lt;br /&gt;
             HandleRegularVertex(&amp;lt;tex&amp;gt;v_{max}&amp;lt;/tex&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
[[Файл:Split-merge - result.png|470px]]&lt;br /&gt;
&lt;br /&gt;
Опишем теперь каждый метод из последнего switch:&lt;br /&gt;
&lt;br /&gt;
 HandleStartVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleSplitVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt; &lt;br /&gt;
    Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В последующих трех функциях обработки вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; происходит обращение к смежному ребру &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt;. Это сделано для вершин, относительно которых внутренняя область &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; лежит справа от них самих (вершина &amp;lt;tex&amp;gt;v_6&amp;lt;/tex&amp;gt;), либо для двух подряд идущих merge вершин, таких как &amp;lt;tex&amp;gt;v_2&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_8&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 HandleEndVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
&lt;br /&gt;
 HandleMergeVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
    edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
    Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
    if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
       Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
    &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 HandleRegularVertex(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
    if (interior of &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; lies to the right of &amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;)&lt;br /&gt;
       then&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{i-1})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          Delete &amp;lt;tex&amp;gt;e_{i-1}&amp;lt;/tex&amp;gt; from T&lt;br /&gt;
          Insert &amp;lt;tex&amp;gt;e_{i}&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{i}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
       else&lt;br /&gt;
          edge &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt;l \cap P&amp;lt;/tex&amp;gt;&lt;br /&gt;
          Search &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; in T&lt;br /&gt;
          if (Type_of_vertex(&amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt; = 'merge')&lt;br /&gt;
             Insert edge(&amp;lt;tex&amp;gt;v_{i}&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;helper(e_{j})&amp;lt;/tex&amp;gt;) in D&lt;br /&gt;
          &amp;lt;tex&amp;gt;helper(e_{j}) \leftarrow  v_i&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Корректность =====&lt;br /&gt;
&lt;br /&gt;
{{Лемма&lt;br /&gt;
|statement=&lt;br /&gt;
Функция ''MakeMonotone(P)'' корректно выполняет разбиение многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Другими словами эта функция добавляет в &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; множество непересекающихся диагоналей, которые разбивают &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; на монотонные части.&lt;br /&gt;
|proof=&lt;br /&gt;
Тот факт, что &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; разбивается на монотонные части следует из предыдущей леммы.&lt;br /&gt;
Остаётся доказать, что диагонали, построенные в процессе выполнения алгоритма, не попарно не пересекаются и не пересекают стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Рассмотрим случай выполнения функции ''HandleSplitVertex'', поскольку это наиболее общий случай: split вершина может быть соединена со всеми типами вершин, в отличие от остальных функций (в них рассматриваемая в данный момент вершина может быть соединена только с merge вершиной). &lt;br /&gt;
&lt;br /&gt;
Допустим, что диагональ &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; была построена с помощью ''HandleSplitVertex'' по достижению split вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Рассмотрим четырёхугольник &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, заключённый между &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_k&amp;lt;/tex&amp;gt; - левым и правым ребром относительно &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и горизонтальными прямыми, проведёнными через &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Внутри  &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, не может находиться ни одной из вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, в противном случае &amp;lt;tex&amp;gt;helper(e_j)&amp;lt;/tex&amp;gt; не равнялся бы &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;. Предположим теперь, что &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; пересекает &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Учитывая, что никаких вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не лежит внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и стороны &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; не пересекаются, то &amp;lt;tex&amp;gt;e_s&amp;lt;/tex&amp;gt; должна пересечь либо отрезок, соединяющий &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, либо &amp;lt;tex&amp;gt;e_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.[[Файл:Pic_of_correctness.jpg‎|400px|thumb|right|1) Вершин внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; находиться не может; 2) &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; может пересекать только рёбра, помеченные зелёным]] Такое возможно только в случае, когда точками пересечения будут являться &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; или &amp;lt;tex&amp;gt;v_m&amp;lt;/tex&amp;gt;, что не противоречит условию. Отсюда &amp;lt;tex&amp;gt;v_{i}v_{m}&amp;lt;/tex&amp;gt; не пересекает ни одну из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в посторонних точках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь рассмотрим случай с пересечением добавленной ранее диагональю. Поскольку внутри &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; никаких вершин вершин находиться не может, и оба конца любой добавленной ранее диагонали должны лежать выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;, диагональ &amp;lt;tex&amp;gt;v_{i}v_m&amp;lt;/tex&amp;gt; не может пересекать никакую из ранее добавленных диагоналей.&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===== Оценкка работы =====&lt;br /&gt;
Построение описанной выше приоритетной очереди &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; происходит за линейное время. Когда заметающая прямая останавливается в вершине: операции с очередью занимают константу по времени, операции с деревом &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на запросы и обновления требуют &amp;lt;tex&amp;gt;\mathcal{O}(\mathcal \log(n))&amp;lt;/tex&amp;gt;. Добавление диагонали в &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt; требует &amp;lt;tex&amp;gt;\mathcal{O}(1)&amp;lt;/tex&amp;gt;. В итоге обработка каждой вершины требует &amp;lt;tex&amp;gt;\mathcal{O}(\log(n))&amp;lt;/tex&amp;gt;, а весь алгоритм соответственно &amp;lt;tex&amp;gt;\mathcal{O}(n \log(n))&amp;lt;/tex&amp;gt;. Что касается памяти, она очевидно составляет &amp;lt;tex&amp;gt;\mathcal{O}(n) &amp;lt;/tex&amp;gt;. Очередь &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; и дерево &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; занимают линейную память.&lt;br /&gt;
&lt;br /&gt;
==== Триангуляция монотонного многоугольника ====&lt;br /&gt;
&lt;br /&gt;
===== Идея =====&lt;br /&gt;
Будем проходить сверху вниз по вершинам многоугольника проводя диагонали где это возможно.&lt;br /&gt;
Отсортируем все вершины многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в порядке убывания их &amp;lt;tex&amp;gt;y&amp;lt;/tex&amp;gt;-координаты. Заведём стек вершин &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. В стеке будем хранить вершины в отсортированном порядке, которые были обработаны, но не были отрезаны от многоугольника, то есть находятся в той части многоугольника, которая ещё не была триангулирована. В момент обработки некоторой вершины, будем пытаться провести из неё как можно больше диагоналей к вершинам, содержащимся в стеке. Эти диагонали отрезают треугольники от &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. На вершине стека будет храниться вершина, которая будет обрабатываться последней.&lt;br /&gt;
&lt;br /&gt;
Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше последней обработанной вершины &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и которая ещё не была триангулирована имеет форму перевёрнутой воронки (см. рисунки). Одна сторона воронки состоит из одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, а другая состоит из цепи вершин, которые лежат выше &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt; и внутренние углы которых не меньше &amp;lt;tex&amp;gt;\pi&amp;lt;/tex&amp;gt;. Несложно догадаться, что самая нижняя вершина стека является единственной выпуклой. Несложно также заметить, что при обработке следующей вершины свойство перевёрнутой воронки сохранится, то есть оно является инвариантом алгоритма.&lt;br /&gt;
&lt;br /&gt;
===== Алгоритм =====&lt;br /&gt;
Рассмотрим процесс обработки вершины более подробно. Возможны два случая:&lt;br /&gt;
* Текущая вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; является нижним концом стороны &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;, ограничивающего воронку. Вершины противоположной цепи уже были положены в стек. В этом случае можно просто построить диагонали, соединяющие &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; со всеми вершинами, находящимися в стеке, кроме последней. Последняя вершина в стеке уже соединена с &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; стороной &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt;. Часть многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, лежащая выше &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt;, которая не была триангулирована, ограничена диагональю, которая соединяет &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; с вершиной &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;, которая была первой в стеке. Сторона многоугольника &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, выходящая из &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; направлена вниз. Снова образуется фигура c одним выпуклым углом, похожая на воронку — инвариант сохраняется. Вершины &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt;  кладутся в стек, поскольку они были были обработаны, но по прежнему являются вершинами непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt;v_j&amp;lt;/tex&amp;gt; принадлежит последовательной цепи вершин, добавленных в &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;. Вынем из стека верхнюю вершину &amp;lt;tex&amp;gt;v_{s1}&amp;lt;/tex&amp;gt; — она уже соединена с &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; одной из сторон &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;. Затем будем пытаться выстраивать диагонали, соединяющие &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; c вынимаемыми из стека вершинами пока это возможно. Проверку на возможность построения диагонали &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt; — текущая верхняя вершина стека, можно осуществлять посредством изучения взаимного расположения предыдущей вершины, вынутой из &amp;lt;tex&amp;gt;S&amp;lt;/tex&amp;gt;, относительно &amp;lt;tex&amp;gt;v_{j}v_{k}&amp;lt;/tex&amp;gt;. Когда мы достигнем вершины  &amp;lt;tex&amp;gt;v_{k}&amp;lt;/tex&amp;gt;, до которой невозможно провести диагональ, положим предыдущую вершину  &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; обратно в стек. Вершина &amp;lt;tex&amp;gt;v_{k-1}&amp;lt;/tex&amp;gt; является либо последней, до которой было возможно провести диагональ, либо, если ни одной диагонали из  &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; провести не удалось, — соседом &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt;. Далее положим &amp;lt;tex&amp;gt;v_{j}&amp;lt;/tex&amp;gt; в стек. Опять же инвариант непротриангулированной части &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; сохраняется: одна сторона воронки ограничена частью стороны многоугольника, а другая цепью невыпуклых вершин.&lt;br /&gt;
&lt;br /&gt;
===== Псевдокод =====&lt;br /&gt;
&lt;br /&gt;
Как ранее уже было отмечено, задаём &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt; в виде рёберного списка c двойными связями &amp;lt;tex&amp;gt;D&amp;lt;/tex&amp;gt;.&lt;br /&gt;
 TriangulateMonotonePolygon(P)&lt;br /&gt;
    vertex [n] V = new vertex(P); // массив вершин &amp;lt;tex&amp;gt;P&amp;lt;/tex&amp;gt;, отсортированный по y-координате в порядке убывания.&lt;br /&gt;
    stack S = new stack();&lt;br /&gt;
    S.push(V[1]);&lt;br /&gt;
    S.push(V[2]);&lt;br /&gt;
    for j \leftarrow 3 to n - 1&lt;br /&gt;
       if (V[j] = S.peek())&lt;br /&gt;
          while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
             if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
                Insert edge(V[j], S.peek()) in D&lt;br /&gt;
             S.pop()&lt;br /&gt;
          S.push(V[j-1])&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
       else&lt;br /&gt;
          vertex last = S.peek();&lt;br /&gt;
          S.pop();&lt;br /&gt;
          while (IsValidDiagonal(edge(V[j], S.peek()), last)) //проверка возможности построения диагонали — предикат &amp;quot;левый поворот&amp;quot;&lt;br /&gt;
             last = S.peek();&lt;br /&gt;
             S.pop();&lt;br /&gt;
             Insert edge(V[j], last) in D&lt;br /&gt;
          S.push(last);&lt;br /&gt;
          S.push(V[j]);&lt;br /&gt;
    S.pop()&lt;br /&gt;
    while (S &amp;lt;tex&amp;gt;\neq  \varnothing &amp;lt;/tex&amp;gt;)&lt;br /&gt;
       if (S.size() &amp;lt;tex&amp;gt;\neq&amp;lt;/tex&amp;gt; 1)&lt;br /&gt;
          Insert edge(V[j], S.peek()) in D&lt;br /&gt;
       S.pop()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Оценка работы =====&lt;br /&gt;
&lt;br /&gt;
=== Ушной метод ===&lt;br /&gt;
Более эффективным я&lt;/div&gt;</summary>
		<author><name>Muravyov</name></author>	</entry>

	</feed>