С,
УДК 681.3
ТРИАНГУЛЯЦИЯ ТРЕХМЕРНОГО СЛОЯ
Н.А. Тюкачев
Предлагается алгоритм построения упорядоченных массивов граничных точек неодносвязной триангуляции
поверхности. Алгоритм используется при построения боковой поверхности трехмерного слоя Ключевые слова: геометрические алгоритмы, граничные точки триангуляции
1 щ и и ли, 1. дддадд^- лии*1
1 еологоразведочные предприятия, в частности АК АЛРОСА, выполняют большой объем поисковых работ. К настоящему времени исчерпан резерв месторождений, которые выходили на дневную поверхность и могли быть открыты маршрутными геологическими исследованиями, либо в результате заверки высококонтрастных магнитных аномалий. С каждым годом алмазопоисковые работы смещаются в районы с все более сложным геологическим строением, что влечет за собой существенное увеличение объемов геофизических исследований и бурения. При проведении алмазопоисковых работ формируются больште массивы разнородной геологической информации. Поэтому открытие новых месторождений невозможно без проведения комплексной интерпретации данных информационных массивов с использованием компьютерных технологий.
Так, например, на участке размером 5 на 5 км могут быть пробурены сотни скважин (рис.
1).
Ч I I ,»ш! I I I
' . ■ ' . ' . •> 1 ' '
т~ * . ■
V 4 ' • * • г » \ •
Ж ^ • ’ "
. • * . • * . •
Рис. 2. Часть вертикального разреза
Однако, информации, полученной в результате бурения, достаточно не только для построения разрезов, но и для построения трехмерного тела (рис. 3), ограниченного поверхностью, состоящей из нерегулярных треугольников (^СТПЧ-сІозесІ^^ пе^огк^
Рис. 1. Точками обозначены скважины
По выделенному ряду в любом порядке скважин строится плоский разрез, на котором изображаются слои породы с различной литологией и стратиграфией (рис. 2).
Тюкачев Николай Аркадиевич - ВГУ, канд. физ.-мат. наук, доцент, тел. (4732) 208470
Рис. 3. Трехмерный слой, ограниченный триангулированной поверхностью
Триангуляцию верхней и нижней поверхности слоя можно построить, используя один из методов, описанных в [1]. Для построения триангуляции боковой поверхности слоя необходимо решить задачу упорядочивания по обходу массива номеров граничных точек верхней или нижней поверхности [3]. Триангулированная поверхность, как это видно на рис. 4, может быть многосвязной и, поэтому, необходимо для каждого фрагмента поверхности по-
строить свои упорядоченный массив номеров граничных точек.
Рис. 4. Упорядоченные по обходу массивы номеров граничных точек
Для поверхности, изображенной на рис. 4, два массива номеров граничных точек должны содержать следующие значения: (66,76,80,88, 100,108,112,114,110,106,94,84,78,68,70,72,86, 74,64,72,58,50,30,32,34,16,32,14,12,10,44,52,54, 48,60,66), (4,18,36,40,42,8,6,20,4).
Триангуляция задается массивом треугольников TrH, каждый элемент которого содержит три номера вершин:
TTr=record
P: array[0..2] of word; end;
Элементы массива P ссылаются на элементы массива вершин PointH, структура которых содержат два поля:
TPoint =record Point : TXYZ;
NumVertex: word; end;
В этой структуре значения поля Point содержит координаты точки, а поля NumVertex - номер вершины в общем массиве вершин проекта, состоящего из многих тел.
Для реализации алгоритма требуется собрать массив всех ребер триангуляции. Элементы массива имеют следующую структуру: TEdges = record // все ребра
p0,p1,p2: word;
Faces: array of word; end;
Поля pi и p2 - номера вершин ребра, поле p0 содержит номер соседней вершины ребра, а поле Faces содержит массив номеров соседних граней.
По массиву Edges создается ориентированный граф граничных точек, узлы которого собираются в массив Node. У каждого узла Node есть массив дуг, соединяющих его с ин-
цидентными узлами. Чаще всего из каждого узла выходит одна дуга, соединяющая граничный узел с одним соседним. Для многосвязных многоугольников с дырками возможны случаи, когда из узла выходят несколько дуг. Структура этого графа приведена ниже.
TEdge=record
NumNode: word; //номер соседнего узла графа
//признак прохождения по ребру Visit : boolean; end;
TNode=record
NumPoint: word; // номер в массиве PointH
// массив ветвей на инцидентные узлы Edge : array of TEdge; end;
Поле NumPoint узла указывает на номер точки в массиве PointH, а поле Edge образует массив дуг на инцидентные узлы. В структуре Edge поле NumNode показывает на номер соседнего узла графа, а поле Visit является признаком прохождения ветви.
Алгоритм определения номеров граничных точек состоит из следующих шагов:
Шаг 1. Собрать массив всех ребер Edges.
Шаг 2. Создать ориентированный граф границы.
Шаг 3. Построить массивы упорядоченных номеров вершин границы.
Шаг 3.1. Найти узел графа, из которого выходит непосещенное ребро. Иначе завершить алгоритм.
Шаг 3.2. Построить эйлеров цикл на графе, собирая в стек пройденные узлы.
Шаг 3.3. Исправить стек с пройденными узлами.
Шаг 3.4. Собрать очередной массив упорядоченных номеров вершин границы.
Шаг 3.5. Вернуться на шаг 3.1.
Рассмотрим каждый шаг алгоритма более подробно.
Первый шаг алгоритм основан на следующем утверждении: каждое ребро триангуляции, т.е. ребро треугольника, может входить или в два треугольника или в один. Если ребро обладает только одним соседним треугольником, то это ребро и его вершины - граничные. Для построения ориентированного графа граничных вершин кроме самих вершин потребуется единственная соседняя точка граничного ребра. Поэтому алгоритм сбора ребер состоит из следующих шагов:
Шаг 1.1. Для всех треугольников, для всех ребер треугольника проверить входит ребро в массив Edges;
Шаг 1.2. Если не входит, то добавить ребро, и зафиксировать номер соседнего треугольника;
Шаг 1.3. Иначе ребро входит в два треугольника - увеличить массив номеров соседних треугольников и зафиксировать номер этого треугольника.
Алгоритм второго шага тоже достаточно прост.
Шаг 2.1. Необходимо перебрать все ребра и проверить условие: длина массива соседних треугольников Faces равна единице;
Шаг 2.2. Если условие выполняется, то, с помощью единственной соседней вершины p0, вычислить направление ребра;
Шаг 2.3. Добавить узлы графа pi и p2.
Направление ребра sign вычисляется по знаку проекции векторного произведения векторов p1p0 и p1p2 на ось z. Ребро добавляется вершине p1, если sign=1 и вершине p2, если sign=-1.
Третий шаг алгоритма в свою очередь состоит из четырех подшагов:
Шаг 3.1. Найти узел графа, из которого выходит непосещенное ребро. Иначе завершить алгоритм.
Шаг 3.2. Построить эйлеров цикл на графе, собирая в стек пройденные узлы.
Шаг 3.3. Исправить стек с пройденными узлами.
Шаг 3.4. Собрать очередной массив упорядоченных номеров вершин границы. Перейти на шаг 3.1.
На подшаге 3.2 необходимо найти эйлеров цикла с началом в узле v. Для реализации алгоритма нахождения эйлерова цикла потребуется рабочий стек Stack и еще один стек для эйлерова пути Path. Напомним алгоритм определения эйлерова пути:
Шаг 3.2.1. Начать движение из узла с номером v, поместив этот номер в стек Stack.
Шаг 3.2.2. Если стек Stack не пуст, то для текущего узла найти ребро, по которому еще не ходили и соединяющее его с инцидентным узлом. Иначе, происходит выход из алгоритма.
Шаг 3.2.3. Если такое ребро найдено то, поместить в стек Stack инцидентный узел, пометить ребро как пройденое, и перейти на шаг 3. Иначе выполнить шаг 5.
Шаг 3.2.4. Если ребро не найдено, то взять номер узла из стека Stack, то есть вернуться
назад, поместить номер узла в стек пути Path и перейти на шаг 3.
Результат работы алгоритма на шагах
3.2.1-3.2.4 накапливается в стеке Path. Например, для графа, представленного на рис. 4, в стеке будут накоплены следующие номера вершин: Path = (0,8,7,1,25,26,1,1,12,11,2,10,9,
2,20,19,2,13,14,2,2,17,18,3,15,16,3,3,4,5,6,0,23,
24, 0,21,22,0).
Рис. 5. Пример графа для многоульника
Для ветвящихся контуров типа, представленного на рис. 5, стек Path не совсем точно отражает путь [2]: во-первых, сильно ветвящиеся вершины, например 1 или 2 или 3, несколько раз подряд попадают в стек; во-вторых, рядом оказываются вершины не соединенные ребрами. Для корректировки пути введем вспомогательный стек PathEnd и массив buf, в который будем складывать номера повторяющихся вершин. Алгоритм состоит из двух проходов. На первом проходе собираем неповторяющиеся узлы в стек PathEnd, а повторяющиеся вершины в массив buf, на втором -вставляем из массива buf узлы, между узлами не соединенными ребрами. Во время первого прохода стек Path разрушается, поэтому приходится создавать вспомогательный стек Pa-thEnd. Первый проход состоит из следующих шагов:
Шаг 3.3.1. Взять номер вершины из стека Path в переменную Old.
Шаг 3.3.2. Если стек Path не пуст, взять номер вершины в переменную v. Иначе выход.
Шаг 3.3.3. Если номера вершин v и Old совпадают, то поместить v в массив buf.
Шаг 3.3.4. Иначе поместить v в стек PathEnd.
Шаг 3.3.5. Назначить Old равным v и перейти к шагу 3.3.2.
Второй проход работает со стеком Pa-thEnd и состоит из шагов:
Шаг 3.3.6. Взять номер вершины из стека PathEnd в переменную Old.
Шаг 3.3.7. Поместить в стек Path.
Шаг 3.3.8. Если стек PathEnd не пуст, взять номер вершины в переменную v. Иначе выход.
Шаг 3.3.9. Найти ребро, у которого первая вершина Old, а вторая - v.
Шаг 3.3.10. Если такое ребро найдено, то поместить v в стек Path. Назначить Old равным v. Перейти к шагу 3.3.8.
Шаг 3.3.11. Иначе найти в массиве buf подходящий узел с номером вершины Old, поместить его в стек Path и перейти к шагу 3.3.9.
В результате работы алгоритма на шагах
3.3.1-3.3.11 стек Path содержит один из возможных эйлеровых путей, который, например, для графа, изображенного на рис. 4, содержит следующие вершины: Path = (0,1,8,
7,1,25,26,1,2,12,11,2,10,9,2,20,19,2,13,14,2, 3, 17,
18,3,15,16,3,4,5,6,0,23,24,0,21,22,0).
На шаге 3.4. из стека Path собирается очередной массив двумерного массива
ABorder упорядоченных номеров вершин границы. Используя этот массив, необходимо добавить к массиву треугольников верхней и нижней поверхности слоя треугольники боковой поверхности, опирающиеся на граничные точки. Каждая граничная точка слоя порождает два новых треугольника. Поэтому, если длина массива граничных точек равна Lp, то массив треугольников увеличится на 2*Lp элементов.
Воронежский государственный университет
Рис. 6. Две триангулированные поверхности соединены в тело боковой триангулированной поверхностью
Для односвязной триангулированной поверхности алгоритм создает одномерный массив граничных точек (рис. 3).
Таким образом в работе предложен алгоритм построения упорядоченных массивов граничных точек триангуляции неодносвязной поверхности. Алгоритм позволяет построить боковую поверхность трехмерного слоя.
Литература
1. Скворцов А.В. Алгоритмы построения и анализа триангуляции. / А.В. Скворцов, Н.С. Мирза. - Томск: Изд-во Том. ун-та, 2006. - 167 с.
2. Тюкачев Н.А. Определение принадлежности точки многоугольнику общего вида методом трассировки луча. // Вестник ВГТУ. 2009, № 5. с. 141-144.
3. Тюкачев Н.А. Программирование графики в Эе1рЫ. / Н.А. Тюкачев, И. В. Илларионов, В. Г. Хлебостроев - СПб., БХВ-Петербург. 2008. - 766 с.
TRIANGULATION OF THE THREE-DIMENSIONAL LAYER
N.A. Tjukachev
The algorithm of construction of the ordered files of boundary points of not one-coherent triangulation of a surface is offered. The algorithm is used at construction of a lateral surface of a three-dimensional layer.
Keywords: geometrical algorithms, boundary points of a triangulation
На рис. 6 представлен результат работы алгоритма: две треангулированные поверхности соединены в единое тело боковой триангулированной поверхностью.