Алгоритм построения триангуляции со структурами triang1 и triang2
Прежде чем рассматривать применяемые на практике алгоритмы триангуляции необходимо уточнить определение триангуляции.
Триангуляция это нахождение множества треугольников, покрывающих все заданные точки множества (т.е. все точки являются вершинами треугольника) и построение структуры данных, содержащей информацию об отношении соседства между треугольниками. Таким образом, с практической точки зрения для построения триангуляции необходимо сформировать структуры: triang1, хранящую информацию о вершинах треугольников, входящих в триангуляцию, и triang2 об отношении соседства треугольников.
Пусть дано некоторое множество точек М. Мощность данного множества точек М равна: |M| = n. Нам необходимо выполнить построение треугольников так, чтобы выполнялись следующие условия:
1. Любая точка из множества М является вершиной треугольника. То есть для любой точки mi I M. существует треугольник mi такой, что точка mi является вершиной треугольника Tj.
2. Для любых двух треугольников Tj, Tk выполняется условие:То есть Tj «не накладывается» на Tk.
= ВО, где ВО - выпуклая оболочка множества М.
3. Для любого треугольника Tj определенны треугольники Tj1, Tj2, Tj3, которые являются соответственно соседями к треугольнику Tj по любой стороне (Tjk = 0, если соответствующие стороны внешние).
4. Постарайтесь проанализировать рассуждения построения триангуляции со структурами triang1 и triang2 с помощью языка программирования Object Pascal но средствам ответов на следующие вопросы:
- Можно ли использовать для хранения координат проставляющихся точек массив pts, каждый элемент которого является записью с двумя полями х и у, содержащими соответствующие координаты данных точек?
- Можно ли применить быструю сортировку Хоара для расположения в порядке возрастания по координате х точки массива pts?
- Можно ли сначала построить выпуклую оболочку данных точек, затем найти точку, ближайшую к «центральной» точке и произвести первоначальное построение триангуляции по этой точке и крайним? Далее определить те треугольники триангуляции, внутрь которых попадают оставшиеся точки исходных точек, не попавшие в триангуляцию, включить их в триангуляцию, перестроив нужным образом соответствующие структуры триангуляции.
- Можно ли организовать массив triang1 множества треугольников, покрывающего заданные точки, следующим образом:
triang1 [(x1,y1), (x2,y2), (x3,y3)] - любой треугольник задаётся тремя вершинами, каждая из которых имеет координаты: (х, у) в массиве pts (в самом массиве triang1 содержатся не координаты точек, а их индексы в массиве pts).
- Можно ли организовать массив triang2 - массив структуры данных, содержащей информацию об отношении соседства между треугольниками, следующим образом:
Triang2 [T1,T2,T3] - каждый треугольник связан отношением соседства с тремя прилегающими к его сторонам треугольникам, причем Tj = 0, если соответствующие стороны внешние.
При ответах на некоторые из поставленных вопросов вам могут помочь следующие теоретические позиции.
Для построения выпуклой оболочки множества данных точек можно использовать уже вам известные алгоритмы построения выпуклой оболочки (см. [5]). Или воспользоваться следующей схемой: выпуклую оболочку представить условно состоящей из двух частей «верхней» и «нижней». Начинаем построение с верхней границы.
В результате сортировки самая «левая» точка (с наименьшей координатой х) находится на первой позиции в массиве, а самая «правая» точка (с максимальной координатой х) на самом последнем месте.
Полагаем первую точку текущей и вычисляем самый «левый» из векторов, направленных к другим точкам множества. Для этого находим синусы углов, образованные этими векторами по формуле:
И выбираем вектор, максимальный по синусу.
Точка, в которую направлен данный вектор, включается в оболочку вслед за текущей точкой. Далее, новую точку полагаем текущей, и для нее опять ищем самый «левый» вектор, при этом рассматриваются только точку с большим значением координаты (рис. 5). Процесс продолжается до тех пор, пока текущей не станет крайняя правая точка.
Рис 5. Самый левый векторАлгоритм построения верхней части выпуклой оболочки можно представить следующим образом:
cur:=t; // Текущая точка (самая левая)
Image1.Canvas.MoveTo(pts[1].x, pts[1].y); // Начинаем рисование с первой точки
white (cur<>n) do begin
max:=cur+1;
dy:=pts[cur].y-pts[cur+1].y;
dx:=pts[cur+1 ].x-pts[cur].x;
sinmax:=dy/sqrt(sqr(dx)+sqr(dy));
for j:=cur+2 to n do begin // Поиск самого левого вектора
dy:=pts[cur].y-pts[j].y;
dx:=pts[ j ].x-pts[cur].x;
sinj:=dy/sqrt(sqr(dx)+sqr(dy));
if sinj>sinmax then begin
max:=j;
sinmax:=sinj
end
end;
Image1.Canvas.
LineTo(pts[max].x,pts [max] .y); // Линия из текущей точки в указанную
Metki[max]:=false; // Отмечаем точку, имеющую макси-
isVerh[max]:-true; мальное значение синуса угла как про-
смотренную и попавшую в верхнюю
часть выпуклой оболочки
cur:=max // Продолжить поиск с найденной точки
end;После этого аналогично строим «нижнюю» часть оболочки. Как вы думаете, какой угол надо рассматривать при этом, и как будет выглядеть алгоритм для данной подзадачи?
Далее начинаем построение триангуляции выпуклой оболочки с нахождения центральной точки из всего множества точек, попавших в выпуклую оболочку, но не являющихся крайними. Для отслеживания принадлежности исходных точек к вершинам выпуклой оболочки в ходе ее построения в программе их необходимо условно «пометить». В качестве центральной точки выбираем точку, которая удовлетворяет следующим условиям:
- Точка не является «помеченной».
- Это должна быть точка, которая находиться как можно ближе к центру выпуклой фигуры.
Отсюда вытекает очевидный алгоритм поиска данной точки:
1. Ищем координаты центра выпуклой фигуры (для этого достаточно найти среднее арифметическое всех точек).
2. Из всех непомеченных точек ищем ту, у которой минимально расстояние до центра.Замечание. На самом деле, алгоритм будет работать, т.е. вычислять одну из триангуляции, и в случае, если центральная точка будет выбрана произвольным образом среди непомеченных. Однако в этом случае чаще будет наблюдаться эффект «вытянутых» треугольников, что отрицательно скажется на эффективности решения большинства прикладных задач с помощью данной триангуляции.
На практике, для экономии времени, можно воспользоваться упорядоченностью массива pts по координате х. Тогда, пробуем выбрать медиану массива по координате х (в силу упорядоченности - элемент на средней позиции), если соответствующая точка помечена, то пробуем соседние по координате х к ней точки, если и они помечены, то соседние по координате х к ним и т.д.
С помощью найденной центральной точки можно построить первоначальное множество треугольников: соединяем все точки, которые являются вершинами выпуклой оболочки с центральной точкой (рис. 6).
Данное множество необходимо описать с использованием структур triang1 и triang2. Для формирования данных структур приведем пример построения триангуляции в ЭВМ. На рис. 7 изображена триангуляция выпуклой оболочки.
Рис. 6. Нахождение центральной точки Рис. 7. Пример триангуляцииСоответствующие массивы: triang1 и triang2 заполняются следующим образом:
triang1 [(x1,y1), (x2,y2), (x3,y3)] - любой треугольник задаётся тремя вершинами, каждая из которых имеет координаты: (x, y) в массиве pts (в самом массиве triang1 содержатся не координаты точек, а их индексы в массиве pts);
triang2 [T1,T2,T3] - каждый треугольник связан отношением соседства с тремя прилегающими к его сторонам треугольникам.
Тогда триангуляция выпуклой оболочки для конкретного примера в ЭВМ решается следующим образом:
Triang1
triang2
t
(1,6,7)
(2,6,0)
2
(6,5,7)
(3,1,0)
3
(5,4,7)
(4,2,0)
4
(4,3,7)
(5,3,0)
5
(3,2,7)
(6,4,0)
6
(2,1,7)
(1,5,0)
Таким образом, в первой строке в скобках (1,6,7) описывается треугольник I, который заключен между 1, 6 и 7 вершинами. Далее во вторых скобках (2,6,0) для этого треугольника указывается отношение соседства: со стороны, заключённой между 6 и 7 вершинами (расположенной напротив 1-й вершины) треугольник I граничит с треугольником II. Со стороны, заключённой между 1 и 7 вершинами (напротив 6-й), треугольник I связан отношением соседства с треугольником пол номером VI. А со стороны, находящейся между точками 1 и 6 (напротив 7-й вершины) соседнего треугольника нет, так как это внешняя сторона, поэтому в triang2 содержится 0. Следует заметить, что расположение вершин в triang1 может быть выбрано произвольно, однако построение triang2 напрямую зависит от triang1. Аналогично представляются остальные треугольники и их соседи.
Таким образом, в результате предыдущих действий мы построили первоначальную триангуляцию с использованием крайних точек выпуклой оболочки и центральной точки (рис. 6). При этом остались точки, которые попали в выпуклую оболочку, но не являются, ни вершинами выпуклой оболочки, ни центральной точкой. Данные точки надо включить и уже имеющуюся триангуляцию. Для этого необходимо для каждой i-й точки, пока не являющейся вершиной ни одною треугольника выполнить следующие действия:
1. Найти треугольник, в который попадает i-я точка.
Для решения данной задачи необходимо обеспечить перебор всех треугольников, и проверять на вхождение точки в каждый из них. Это легко реализовать с помощью векторного произведения (рис. 8, 9).
Рис. 8. Проверка точки на вхождение в треугольникПри этом точка лежит внутри треугольника, тогда и только тогда, когда все знаки векторных произведений , , совпадают.
2. Найденный треугольник, внутри которого лежит точка, следует разбить на 3 части, используя внутреннюю точку i, т.е. перестроить массив треугольников triang1 и массив соседства triang2.
Итак, следующим этапом изучения алгоритма построения триангуляции со структурами triang1 и triang2 является практическая реализация данного алгоритма. В табл. 2 приведен листинг каркаса программы, комментарии и методические рекомендации для реализации данного проекта. Конечный вариант вида формы может иметь следующий вид (рис. 10).
Рис. 9. Векторные произведения, необходимые для проверки на принадлежность точки треугольнику
Рис. 10. Вил формы построения триангуляции со структурами triang1 и triang2
Вам необходимо заполнить пропуски в соответствии с рекомендациями, приведенными в качестве комментариев непосредственно в программном продукте и в методических рекомендациях. Вы можете использовать предыдущий программный продукт, а также ранее вами изученные и реализованные на практике (см. [5]).
Таблица 2.
Листинг модуля формы, комментарии и методические рекомендации программы построения триангуляции со структурами triang1 и triang2